. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
刷新 | 提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->第一个程序
  管理员: assembly   [回复本贴] [收藏本贴] [管理本贴] [关闭窗口]
主题 : :  实验3的问题,第一版书中的add sp,4,请会的人解答  [待解决] 回复[ 30次 ]   点击[ 1545次 ]  
linwangfeng
[帖 主]   [ 发表时间:2009-05-02 12:08 ]   [引用]   [回复]   [ top ] 
荣誉值: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
麻烦会的同志解释这是为什么?
acool
[第1楼]   [ 回复时间:2009-05-04 15:42 ]   [引用]   [回复]   [ top ] 
荣誉值:49
信誉值:0
注册日期:2008-10-15 16:15
第二版把这个地方改成add sp,10就是为了屏蔽这个问题,原因是实dos下调试那个程序都没问题,但是保护模式下的虚拟dos就会出问题(可以看看你附注一)

原因是当debug用t命令执行执行时,会往栈中压入几个数据保存当前的状态,以便于后面正确执行,而当sp过小时压入数据sp值就会发生环绕,而这样保护模式会认为程序有问题进而杀死它。即上面提示的错误。
455139
[第2楼]   [ 回复时间:2009-06-07 09:45 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-05-29 14:22
多谢1楼了  我就是一直困在这个地方了,看了一楼的说法才恍然大悟,原来是这样........终于过了,感激不尽!!!
sjy9816
[第3楼]   [ 回复时间:2009-06-29 15:44 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:6
注册日期:2009-06-21 14:14
我刚刚也要问这个问题来,谢谢1楼了!
semidotnet
[第4楼]   [ 回复时间:2009-08-25 23:30 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-08-08 13:43
顶个,我也在这里有困惑。
647647fans
[第5楼]   [ 回复时间:2010-04-28 18:06 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:4
注册日期:2010-04-02 13:09
为什么我在这通过了呢?
很奇怪
不管是add sp,4 
还是add sp,10都行啊
hanqiang
[第6楼]   [ 回复时间:2010-07-15 21:35 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2010-07-07 20:39
学习中
wuchaofanaa
[第7楼]   [ 回复时间:2010-07-27 09:03 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2010-07-22 11:46
学习了后面的章节 就知道出错是因为没有选择一段安全的内存空间,与操作系统冲突了,在实模式下应该不会出错吧
runtowhere
[第8楼]   [ 回复时间:2010-10-26 11:42 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2010-10-12 22:56
我这两天也一直在纠结这个问题!谢谢楼主代问了1
nokeep
[第9楼]   [ 回复时间:2010-10-29 16:37 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2010-10-28 08:45
回压入什么数据保存当前的状态啊
betterpursuel
[第10楼]   [ 回复时间:2010-11-21 18:54 ]   [引用]   [回复]   [ top ] 
荣誉值:8
信誉值:0
注册日期:2010-11-07 17:01
我的两种情况在pop ax时,都报错了,不知道是为什么呢
sugar
[第11楼]   [ 回复时间:2010-12-26 13:26 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2010-12-21 20:28
回复:[第10楼]
------------------
你的程序改成add sp,10 后应该可以正常运行了
goodxiaowan
[第12楼]   [ 回复时间:2011-01-02 09:33 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2010-05-23 12:24
如想知道当debug用t命令执行时,会往栈中压入那些数据,就到我的博客“ 实验2 之3.19的实验过程 ”
一定会给你带来惊喜!
waybq
[第13楼]   [ 回复时间:2011-02-19 15:50 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2008-08-26 18:13
这里还真能学知识
mayjian
[第14楼]   [ 回复时间:2011-04-14 20:10 ]   [引用]   [回复]   [ top ] 
荣誉值:4
信誉值:0
注册日期:2011-04-12 20:28
我也遇到这个问题,在虚拟DOS下有什么方法可以使t正常执行
qiuguo
[第15楼]   [ 回复时间:2011-04-14 22:44 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-04-11 21:40
我也是这个问题,不过,我的没有报错,而是当运行完pop ax之后,它后面的代码是int3,push bp,.....运行了很多句后,才到pop bx,,这又是什么原因
rikka_wang
[第16楼]   [ 回复时间:2011-04-16 21:12 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-03-20 20:30
2楼的兄弟 ADD SP,10这条指令会不会还暗示了这个程序所定义的栈的大小10BIT呢?
如果这个栈大小没有受限制,超栈是很危险的!!!
liash
[第17楼]   [ 回复时间:2011-07-31 10:32 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-07-29 21:21
2楼的兄弟 ADD SP,10这条指令会不会还暗示了这个程序所定义的栈的大小10BIT呢?
如果这个栈大小没有受限制,超栈是很危险的!!!
------------------
回复:ADD SP,10 这句话什么意思???
chinatree
[第18楼]   [ 回复时间:2011-07-31 14:35 ]   [引用]   [回复]   [ top ] 
荣誉值:118
信誉值:0
注册日期:2011-07-07 22:59
把sp+10喽,也就是把栈空间加大一些,省的栈顶超界
304590484
[第19楼]   [ 回复时间:2012-02-23 12:54 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2012-02-21 20:39
我看了你的那篇了,我有个问题,你在后面有试加了mov bp,02上去,中断后执行了mov ss,ax后面的mov bp,02,我在未执行mov sp,20的情况下看了寄存器内容,发现已经有数据写到了2000:0020的栈中,我疑惑并未执行mov sp,20,系统如何知道是存到2000:0020而不是其他?
304590484
[第20楼]   [ 回复时间:2012-02-23 12:58 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2012-02-21 20:39
我们在后面对栈的操作会修改栈中的数据,不会影响到压入数据保存的状态吗?
tomato
[第21楼]   [ 回复时间:2012-02-23 15:50 ]   [引用]   [回复]   [ top ] 
荣誉值:405
信誉值:0
注册日期:2008-01-19 14:51
不会影响。
sz_hgc
[第22楼]   [ 回复时间:2012-08-15 00:39 ]   [引用]   [回复]   [ top ] 
荣誉值: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中的值 所以程序出错。!

我是新手,刚学到这里,以上是我的理解,有错误的地方 还请指点  谢谢
sz_hgc
[第23楼]   [ 回复时间:2012-08-15 00:41 ]   [引用]   [回复]   [ top ] 
荣誉值: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中的值 所以程序出错。!

我是新手,刚学到这里,以上是我的理解,有错误的地方 还请指点  谢谢
refyzd
[第24楼]   [ 回复时间:2012-08-16 14:33 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2012-07-30 12:23
学习了
mingge
[第25楼]   [ 回复时间:2014-05-03 12:44 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2014-03-05 20:46
正郁闷这个问题呢
qazsewq
[第26楼]   [ 回复时间:2014-10-07 22:54 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2014-10-06 00:22
貌似中断用了12个字节,但为什么保护模式下恢复用了10个就可以了?剩下的一个字节有什么用吗?高手指点下。
iamalian
[第27楼]   [ 回复时间:2015-05-18 09:53 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-03-16 22:48
22楼的实验好详细,把问题也说得很明白,赞!!!
vs9841
[第28楼]   [ 回复时间:2015-10-13 11:00 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-01-17 12:29
用tr调试,就不会产生这个问题,debug的调试能力,还是弱了一点
需要登录后才能回帖 -->> 请单击此处登录
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved