当我运行我的程序时,汇编程序说:
程序已恢复对操作系统的控制
到达 RET 指令时。代码如下:
twoMash PROC
push bp
mov bp, sp
sub sp, 2
NOT ax
ADD ax,1
mov sp,bp
ret
twoMash ENDP
main
以这种方式定义:
main:
mov ax,100b
push ax
call twoMash
答案 0 :(得分:2)
第一条指令是push bp
,因此堆栈顶部的值现在是bp
的值。
然后你做了更多的事情,包括操纵sp
(指向堆栈顶部的指针),但在ret
之前它指向旧的bp
值。
ret
将从堆栈中弹出值,并将ip
(指令指针)设置为该值。在正常情况下,它应该在堆栈顶部具有要执行的下一条指令的地址(通常由call
指令放置,执行ret
的反作用,推送下一条指令的地址堆栈上有call
,然后将ip
设置为call
指令中的参数值。
但是在你的代码中,ip
被设置为旧的bp
值,这很可能指向某处堆栈内存(或“更糟糕”),因此CPU将接下来尝试执行数据字节代码,行为是意外的(返回操作系统实际上是非常好的最终结果,这种错误通常以应用程序崩溃或数据丢失而告终。)
要解决此问题,请在pop bp
之前添加ret
(将sp
值恢复为mov sp,bp
后)。
每当您通过push/pop
或add/sub sp
显式操作堆栈,或者call/ret
隐式操作堆栈时,请确保在使用之前在每个代码路径中以正确的sp
值结束进一步堆叠。 IE浏览器。通常每个push
需要配对pop
,每个call
应该由ret
返回,除非您有足够的经验打破这些规则并通过不同方式调整堆栈以纠正状态。
call
,那么您的问题就不清楚了这个,或者它是你的程序的入口点。)
如果这是DOS可执行文件,并且它是入口点,那么您应该使用int 21h, 4Ch
OS服务调用结束您的程序。