Using CALL, RET in x86 assembly

Consider the following simple assembler code that uses push , pop and call

 CDSEG SEGMENT MAIN PROC FAR ASSUME CS:CDSEG,DS:DTSEG MOV AX,DTSEG MOV DS,AX MOV AX,1010H ; (1) PUSH AX ; (2) CALL FOO ; (3) ADD AX,2 ; (7) MAIN ENDP FOO PROC POP AX ; (4) ADD AX,1 ; (5) RET ; (6) FOO ENDP END MAIN 

What I expect is to see

 (1) ax = 1010h, stack=???? (2) ax = 1010h, stack=1010h (3) (4) ax = 1010h, stack=???? (5) ax = 1011h (6) (7) ax = 1012h 

but the emulator shows

 (1) ax = 1010h, stack=???? (2) ax = 1010h, stack=1010h (3) (4) ax = 000Ch, stack=???? (5) ax = 000Dh (6) The control never goes back to the main proc (7) ??? 

What mistake?

+1
assembly x86
source share
1 answer

CALL pushes the return address onto the stack, which allows RET return to this address. When you POP AX to FOO , you pull the return address from the stack. The value of PUSH ed before CALL not on the top of the stack when entering FOO , but rather in [SP+2] .

+5
source share

All Articles