The confusing thing about LEA is that the source operands are within a '[]' block which makes it look like a memory access.
I'd love to know why that is.
I think the calculation is also done during instruction decode rather than on the ALU, but I could be wrong about that.
LEA is the equivalent of & in C. It gives you the address of something.
Fun question: what does the last line of this do?
MOV BP,12 LEA AX,[BP] MOV BX,34 LEA AX,BX
It (LEA) does all the work of a memory access (the address computation part) without actually performing the memory access.
Instead of reading from memory at "computed address value" it returns "computed address value" to you to use elsewhere.
The intent was likely to compute the address values for MOVS/MOVSB/MOVSW/MOVSD/MOVSQ when setting up a REP MOVS (or other repeated string operation). But it turned out they were useful for doing three operand adds as well.