在程序集x86中使用CALL,RET

时间:2016-04-12 09:11:09

标签: assembly x86

考虑以下使用pushpopcall

的简单汇编代码
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

我的期望是看

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

但是,模拟器显示

(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) ???

是什么错?

1 个答案:

答案 0 :(得分:5)

CALL推送堆栈上的返回地址,这允许RET返回该地址。当您POP AX FOO时,您将从堆栈中弹出返回地址。当您输入PUSH,而不是CALL时,FOO之前[SP+2]的值不在堆栈顶部。