王爽汇编语言第六章程序6.3单步调试看不懂assume cs:codecode segmentdw 0123h,0456h,0789h,0abch,0defh,0
王爽汇编语言第六章程序6.3单步调试看不懂
assume cs:code
code segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
dw 0,0,0,0,0,0,0,0
start: mov ax,cs
mov ss,ax
mov sp,32h
mov bx,0
mov cx,8
s:push cs:[bx]
add bx,2
loop s
mov bx,0
mov cx,8
s0:pop cs:[bx]
add bx,2
loop s0
mov ax,4c00h
int 21h
code ends
end start
执行完 mov ss,ax后,下一步执行ADC AX,[BX+SI] 下一步应该执行mov sp,32h啊?接着后面的单步调试就更看不懂了,这就不一一细说了,而且从S循环和S0循环看,应该循环了3*8+3*8次,也就是至少要单步调试50次 程序才结束的啊!而我没按几个T就执行结束了,这里到底是什么原因?
[解决办法]1.程序循环次数是s——8次,s0——8次,总共16次
2.mov ss,ax
mov sp,32h是连续执行的,避免中断干扰堆栈初始化;
3.程序代码段的可执行代码对应的偏移地址范围是0--48H,而SP=32h,恰处于这一范围,所以堆栈初始化完成后,2EH、2FH、30H、31H的原有代码就被入栈的“0DFEH”和堆栈段段地址覆盖了。也就是堆栈初始化后中间的几个字节的代码因为数据入栈而被破坏了。如果想避免这种情况的话,就把SP设大些。
[解决办法]我觉得二楼的第三个答案楼主要注意理解下
首先举个例子
例如0000:0010到0000:0000首先设置为0
你设置ss为0000
而sp为0010
则0000:0010h到0000:0000之间由于设置了sp会导致0000:0010之前的某些数据(10h前8个字节)会被修改(可以在DEBUG用d命令来查看,在d 0000:0000 - 0000:0010 会被设置成其他数据,我也不知道为啥^^..不过应该是计算机内的一种机制吧^^)
然后在看看代码段
前面设置了8 * 2 * 2 byte = 36 byte
设置了ss为cs
sp为32h = 3 * 16 + 2 = 48 + 2 = 50
又因为设置sp的前八个数据会被修改
因此50 - 8 = 42(也就是说第四十二个字节开始的数据会被修改)
由于前36个字节是用来存储数据的
mov ax,cs
mov ss,ax
mov sp,32h
占了3 * 2 = 6 byte的数据
36 + 6 = 42
mov bx,0这条指令就是在42之后开始的
而由于修改了指令
因此这条指令也被修改成了mov bx,29E6
后面的数据也就乱了
也因此后面的调试步骤乱了