在王爽老师的《汇编语言》195页有这样一个程序:
assume cs:code
stack segment
dw 8 dup (0)
stack ends
code segment
start:
mov ax,stack
mov ss,ax
mov sp,16
mov ds,ax
mov ax,0
call word ptr ds:[0eh]
inc ax
inc ax
inc ax
mov ax,4c00h
int 21h
code ends
end start
大家都能看出,程序执行后ax的值为3,但书中说明“对于此程序,在DEBUG中单步跟踪的结果,不能代表CPU的实际执行结果”,我在DEBUG试验了一下,发现在执行call指令时,会把IP设置为3302h(我的机器是这样),而不是11h,请问这是为什么呢?
------解决方案--------------------
这样的程序,其实并不适合初涉汇编的人来看和理解的。
关键是那个 call word ptr ds:[0eh] 指令,如果是 debug 单步的话,单步中断会使用到程序的堆栈进而改变其中的内容,导致这个 call 指令转到意外的地方而致失控。如果直接运行中间没有被中断,ds:[0eh] 处初始就是 0000,那么 call 指令就会再次转到 start: 处并将返回地址即第一个 inc ax 指令的地址压栈到 ds:[0eh] 处,这样程序再次执行到这个 call 指令时,就会转到下面的 inc ax 指令直至程序的结束。
这纯粹是静态分析出来的结果,一旦调试,堆栈内容被破坏,结果就会大相径庭。