Raúl Gutiérrez Sanz says:
April 12, 2014 at 7:55 pm
LEA AX,DX: As Joshua Rodd said, it loads AX with the last computed effective address. and I would add: Excluding addresses computed for flow control (addresses to be stored in IP).
LEA computes the memory address of the 2nd parameter and seems to store this address in an internal register before storing it in the 1st parameter. If the 2nd parameter is not in memory, no computation is done, and LEA seems to take the previous contents left in this internal register.
So, the general case is that LEA AX,DX after an instruction whose parameter is [1234h], will load 1234h in AX, regardless of DX.
After XLAT, it will load BX+AL.
After PUSH, PUSHF, POPF and CALL it will load the resulting SP. Presumably the same for INT, RET and IRET, but I had no time to test them.
After POP it will also load the resulting SP, except for POP [1234h] (it will load 1234h).
JMP will not alter the last computed address, except for JMP [1234h].
After LES and LDS, it will load the parameter address + 2. In the 8088 it could be different.
CMPSB and CMPSW seem to calculate the instruction of next elements after performing the comparison (to update SI and DI), and they update SI first and DI next. So, after those instructions, the updated DI will remain in the internal register.
Raúl Gutiérrez Sanz says:
April 19, 2014 at 12:32 pm
“After PUSH, PUSHF, POPF and CALL it will load the resulting SP. Presumably the same for INT, RET and IRET, but I had no time to test them.”
Confirmed, but one exception: After RET N, LEA AX,DX will load SP – N in AX (because RET N discards parameters, but does not access them).
It’s also worth noting that INT seems to PUSH the return address after reading the interrupt handler address from the vector table.