. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->第一个程序
主题 : :  实验3的问题,第一版书中的add sp,4,请会的人解答  [待解决] 回复[ 30次 ]   点击[ 1562次 ]  
linwangfeng
[帖 主] [ 发表时间:2009-05-02 12:08 ] 
荣誉值:0
信誉值:0
注册日期:2009-04-15 18:50
1.就书上的代码
code segment
        mov ax,2000h
        mov ss,ax
        mov sp,0
        add sp,4
        pop ax
        pop bx
        push ax
        push bx
        pop ax
        pop bx
        mov ax,4c00h
        int 21h
code ends
end
这里运行到pop ax时会出现错误,大家可能都遇到过。而当我把代码换成

2
code segment
        mov ax,2000h
        mov ss,ax
        mov sp,4
        ;add sp,4
        pop ax
        pop bx
        push ax
        push bx
        pop ax
        pop bx
        mov ax,4c00h
        int 21h
code ends
end
时,代码执行到pop ax时,没有报错误,而是直接退出
Program terminated normally
麻烦会的同志解释这是为什么?
sz_hgc
[第23楼] [ 回复时间:2012-08-15 00:41 ] 
荣誉值:0
信誉值:0
注册日期:2012-07-21 21:21
溢出产生的错误 (所以第二版把add sp,4  改成了 add sp,10)

通过调试我发现把add sp,4这句中的4改成6或比6大程序就可以正常运行。这是怎么回事呢。原因是当我们用debug调试程序的时候执行完一句debug会产生中断,并把当前寄存器IP、CS和flags中的数据压入栈,待执行下一条语句的时候从中恢复。当我们执行add sp,4的时候,由于离栈顶0只剩下4个字节的空间即0~3 而当我们用debug调试程序的时候执行完一句debug会产生中断,并把当前寄存器IP、CS和flags中的数据压入栈,需要6个字节空间,所以就产生溢出了,待执行下一条语句pop bx的时候,debug要恢复寄存器中的数据的时候就出错了,因为保存值溢出了。所以栈顶要保留至少6个字节空间就不会出错了。

调试过程如下:
-------------------------------------

D:\ASM>debug t1.exe
-t

AX=2000  BX=0000  CX=0015  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000
DS=1423  ES=1423  SS=1433  CS=1433  IP=0003   NV UP EI PL NZ NA PO NC
1433:0003 8ED0          MOV     SS,AX
-t

AX=2000  BX=0000  CX=0015  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000
DS=1423  ES=1423  SS=2000  CS=1433  IP=0008   NV UP EI PL NZ NA PO NC
1433:0008 83C404        ADD     SP,+04
-d 2000:0
2000:0000  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................  
2000:0010  1B D1 E3 D1 D2 8B CB 8B-FA D1 E3 D1 D2 D1 E3 D1   ................
2000:0020  D2 03 D9 13 D7 03 D8 83-D2 00 EB DC 93 9D 75 07   ..............u.
2000:0030  F7 D8 83 D2 00 F7 DA 5F-5E 8B E5 5D CB 56 33 F6   ......._^..].V3.
2000:0040  B9 36 00 32 E4 FC AC 32-E0 E2 FB 80 F4 55 74 09   .6.2...2.....Ut.
2000:0050  B8 01 00 50 9A C9 0C B4-1E 5E CB B8 02 00 E9 90   ...P.....^......
2000:0060  F5 55 8B EC 56 57 1E FC-1E 07 8B 4E 08 41 80 E1   .U..VW.....N.A..
2000:0070  FE 8B 7E 06 33 DB 8C D8-8C D2 3B C2 75 03 BB 82   ..~.3.....;.u...
-
//我们看到这时2000:0~2000:f这段内存空间是空的;继续执行:


-t

AX=2000  BX=0000  CX=0015  DX=0000  SP=0004  BP=0000  SI=0000  DI=0000
DS=1423  ES=1423  SS=2000  CS=1433  IP=000B   NV UP EI PL NZ NA PO NC
1433:000B 5B            POP     BX
-d 2000:0
2000:0000  33 14 1D 0E 00 00 00 00-00 00 00 00 00 00 00 00   3...............
2000:0010  1B D1 E3 D1 D2 8B CB 8B-FA D1 E3 D1 D2 D1 E3 D1   ................
2000:0020  D2 03 D9 13 D7 03 D8 83-D2 00 EB DC 93 9D 75 07   ..............u.
2000:0030  F7 D8 83 D2 00 F7 DA 5F-5E 8B E5 5D CB 56 33 F6   ......._^..].V3.
2000:0040  B9 36 00 32 E4 FC AC 32-E0 E2 FB 80 F4 55 74 09   .6.2...2.....Ut.
2000:0050  B8 01 00 50 9A C9 0C B4-1E 5E CB B8 02 00 E9 90   ...P.....^......
2000:0060  F5 55 8B EC 56 57 1E FC-1E 07 8B 4E 08 41 80 E1   .U..VW.....N.A..
2000:0070  FE 8B 7E 06 33 DB 8C D8-8C D2 3B C2 75 03 BB 82   ..~.3.....;.u...

当我们执行完 add sp,4 我们发现2000:0~2000:3 这段内存空间的数据有改变,其实这就是debug中断时压出栈中的数据,分别是flags cs ip 由于我们把sp的值设置为4栈顶空间只有四个内存单元所以只看到了flags寄存器的值0E1DH 和CS的值1433H 而IP的值哪里去了 溢出了..

-d 2000:fff0
2000:FFF0  00 00 00 00 00 00 00 20-00 00 00 20 00 00 0B 00
-
IP的值跑这里去了。 2000:fffe~2000:ffff 也就是000B

所以下执行下一句程序的时候 debug不能正确恢复cs ip flags中的值 所以程序出错。!

我是新手,刚学到这里,以上是我的理解,有错误的地方 还请指点  谢谢
需要登录后才能回帖 -->> 请单击此处登录
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved