本文主要是介绍8086汇编栈段为何“乱套”了,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
带学生在课堂上观察在子程序调用时机器内部发生变化的细节。
有同学关注到了栈中的“乱套”。
程序如下:
assume cs:code, ss:stack
stack segmentdb 16 dup (0)
stack ends
code segment
start: mov ax,stackmov ss,axmov sp,16mov ax,1000call s ;调用子程序mov ax,4c00hint 21hs: add ax,ax ;子程序开始ret ;子程序返回
code ends
end start
编译、连接,并在debug中运行后,界面是:
容易推算出,此时的栈空间为076A:0到076A:F。
乱子始于执行MOV SS, AX
。并且,本来单步执行一条指令,但MOV SP, 10H
没有出现,但,SP的值的确已经变了。
MOV SP, 10H
执行过了——是debug自己干了,没有给程序员单步的机会。这个和中断机制相关(在王爽教材12.11和12.12有详细解释,在此不详述)。
再往后走,可以看见CALL指令执行过程中,栈是按照我们想到的机制进行。
把程序改一下:
assume cs:code, ss:stack
stack segmentdb 16 dup (0)
stack ends
code segment
start: mov ax,stack;mov ss,ax ;把这一句加了注释mov sp,16mov ax,1000call s ;调用子程序mov ax,4c00hint 21hs: add ax,ax ;子程序开始ret ;子程序返回
code ends
end start
运行后的界面:
可见,引起栈变化的,就是MOV SP, 10H
。(这时,没有给SS寄存器赋正确的值,这是危险的,SS保持初进入时的0769H。但为了观察,也就这样捣乱一下看看。)
再往后走,可以看见CALL指令的执行,是按照我们想到的机制进行。
-----
初步结论:栈段的“乱套”,来自于修改SP的值。
引申解释:修改SP的值时,存在着某种机制使用了栈,从而给栈中留下了一些数据。其实这些数据应该不是随便的乱数据,当知道更多时,可以找出这些数据的之所以来。
遗留问题的解决:或许可以从中断机制中可以找出一些线索,留待以后再说。
这篇关于8086汇编栈段为何“乱套”了的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!