CODE SEGMENT
...
MAIN PROC ... MOV AX,1111H PUSH AX CALL SUBPROC ... MAIN ENDP SUBPROC PROC MOV AX,2222H PUSH AX POP AX RET SUBPROC ENDP
...
CODE ENDS
END MAIN
CALL指令执行时,会先把返回地址压入堆栈,再形成子程序入口地址,最后把控制权交给子程序。
一、返回地址:
根据子程序的调用方式分为两种,
1、段内调用:把CALL之后的那条指令地址的偏移量部分(当前IP或EIP值)压入堆栈
2、段间调用:把返回地址(当前IP/EIP值和CS值)压入堆栈,注意如果是在保护模式下,CS应以双字入栈,其高16为无意义。
二、形成子程序入口地址:
将子程序中第一条指令的地址赋给CS和IP。
三、返回:
调用RET将直接从栈顶弹出IP/EIP(或CS和IP/EIP)根据具体情况而定,因为是直接从栈顶弹出,所以如果在子程序结束要返回的时候,栈顶指针不指向返回地址的话,那么程序就可能会崩溃。
如上例,堆栈存储情况如下: