Assembly 程序已将控制权返回到程序集8086中的操作系统
当我运行程序时,汇编程序会说: 程序已将控制权返回到操作系统 当它到达RET指令时。代码如下所示:Assembly 程序已将控制权返回到程序集8086中的操作系统,assembly,x86,x86-16,emu8086,Assembly,X86,X86 16,Emu8086,当我运行程序时,汇编程序会说: 程序已将控制权返回到操作系统 当它到达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 第一条指令是push bp,因此堆栈顶部的
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
第一条指令是
push bp
,因此堆栈顶部的值现在是bp
中的值
然后再做一些事情,包括操纵sp
(指向堆栈顶部的指针),但就在ret
之前,它指向旧的bp
值
ret
将从堆栈中弹出值,并将ip
(指令指针)设置为该值。在正常情况下,它应该在堆栈顶部有下一条要执行的指令的地址(通常通过call
指令放在那里,它执行ret
的反操作,在堆栈上的call
之后推送下一条指令的地址,然后将ip
设置为call
指令的参数值)
但是在您的代码中,ip
被设置为oldbp
值,这很可能指向堆栈内存中的某个地方(或“更糟”),因此CPU接下来将尝试以代码形式执行数据字节,而这种行为是意外的(返回操作系统实际上是非常好的最终结果,这种错误通常会导致应用程序崩溃,甚至数据丢失)
要修复,请在ret
之前添加pop bp
(通过mov sp、bp
还原sp
值后)
无论何时,无论是通过push/pop
或add/sub sp
显式操作堆栈,还是通过call/ret
隐式操作堆栈,在进一步使用堆栈之前,确保在每个代码路径中以正确的sp
值结束。也就是说,通常每个push
都需要它的配对pop
和每个调用ld通过ret
返回,除非您有足够的经验打破这些规则并通过不同的方法将堆栈调整到正确的状态
顺便说一句,在你的入口点的堆栈中是否真的有返回地址是值得怀疑的(你的问题不清楚,如果你有其他代码调用这个,或者它是你程序的入口点)
如果这类似于DOS可执行文件,并且它是入口点,那么您应该使用OS服务调用来结束您的程序。您使用的是哪种汇编程序?而且,这个问题没有意义。当您运行程序时,汇编程序会做些什么?当您运行问题时,汇编程序不会执行。尝试执行时,您是否看到此消息汇编您的代码,或者在尝试运行二进制文件时?您确定这实际上是一个错误吗?您的问题是什么?调用twoMash后的代码是什么?您没有发布它,但它可能会结束程序(例如mov ax,4c00h
,int 21h
)。可能这就是你的程序结束的原因,因为没有更多的代码。你创建了COM程序还是EXE?COM程序中应该有org 100h
。我想知道你是否创建了一个COM程序,twoMash函数先被执行,到达RET,然后返回操作系统而没有到达main
。这是很难说,除非我们看到了你的完整代码。