|
主题 : : 实验3的问题,第一版书中的add sp,4,请会的人解答 [待解决] |
回复[ 30次 ]
点击[ 1545次 ] | |
|
|
|
|
[帖 主]
[ 发表时间: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
麻烦会的同志解释这是为什么? | | |
|
|
|
|
[第1楼]
[ 回复时间:2009-05-04 15:42 ]
[引用]
[回复]
[ top ] | |
荣誉值:49
信誉值:0
注册日期:2008-10-15 16:15 |
第二版把这个地方改成add sp,10就是为了屏蔽这个问题,原因是实dos下调试那个程序都没问题,但是保护模式下的虚拟dos就会出问题(可以看看你附注一)
原因是当debug用t命令执行执行时,会往栈中压入几个数据保存当前的状态,以便于后面正确执行,而当sp过小时压入数据sp值就会发生环绕,而这样保护模式会认为程序有问题进而杀死它。即上面提示的错误。 | | |
|
|
|
|
[第2楼]
[ 回复时间:2009-06-07 09:45 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-05-29 14:22 |
多谢1楼了 我就是一直困在这个地方了,看了一楼的说法才恍然大悟,原来是这样........终于过了,感激不尽!!! | | |
|
|
|
|
[第3楼]
[ 回复时间:2009-06-29 15:44 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:6
注册日期:2009-06-21 14:14 |
|
|
|
|
|
[第4楼]
[ 回复时间:2009-08-25 23:30 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-08-08 13:43 |
|
|
|
|
|
[第5楼]
[ 回复时间:2010-04-28 18:06 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:4
注册日期:2010-04-02 13:09 |
为什么我在这通过了呢?
很奇怪
不管是add sp,4
还是add sp,10都行啊 | | |
|
|
|
|
[第6楼]
[ 回复时间:2010-07-15 21:35 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-07-07 20:39 |
|
|
|
|
|
[第7楼]
[ 回复时间:2010-07-27 09:03 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-07-22 11:46 |
学习了后面的章节 就知道出错是因为没有选择一段安全的内存空间,与操作系统冲突了,在实模式下应该不会出错吧 | | |
|
|
|
|
[第8楼]
[ 回复时间:2010-10-26 11:42 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-10-12 22:56 |
|
|
|
|
|
[第9楼]
[ 回复时间:2010-10-29 16:37 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-10-28 08:45 |
|
|
|
|
|
[第10楼]
[ 回复时间:2010-11-21 18:54 ]
[引用]
[回复]
[ top ] | |
荣誉值:8
信誉值:0
注册日期:2010-11-07 17:01 |
我的两种情况在pop ax时,都报错了,不知道是为什么呢 | | |
|
|
|
|
[第11楼]
[ 回复时间:2010-12-26 13:26 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-12-21 20:28 |
回复:[第10楼]
------------------
你的程序改成add sp,10 后应该可以正常运行了 | | |
|
|
|
|
[第12楼]
[ 回复时间:2011-01-02 09:33 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-05-23 12:24 |
如想知道当debug用t命令执行时,会往栈中压入那些数据,就到我的博客“ 实验2 之3.19的实验过程 ”
一定会给你带来惊喜! | | |
|
|
|
|
[第13楼]
[ 回复时间:2011-02-19 15:50 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2008-08-26 18:13 |
|
|
|
|
|
[第14楼]
[ 回复时间:2011-04-14 20:10 ]
[引用]
[回复]
[ top ] | |
荣誉值:4
信誉值:0
注册日期:2011-04-12 20:28 |
我也遇到这个问题,在虚拟DOS下有什么方法可以使t正常执行 | | |
|
|
|
|
[第15楼]
[ 回复时间:2011-04-14 22:44 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-04-11 21:40 |
我也是这个问题,不过,我的没有报错,而是当运行完pop ax之后,它后面的代码是int3,push bp,.....运行了很多句后,才到pop bx,,这又是什么原因 | | |
|
|
|
|
[第16楼]
[ 回复时间:2011-04-16 21:12 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-03-20 20:30 |
2楼的兄弟 ADD SP,10这条指令会不会还暗示了这个程序所定义的栈的大小10BIT呢?
如果这个栈大小没有受限制,超栈是很危险的!!! | | |
|
|
|
|
[第17楼]
[ 回复时间:2011-07-31 10:32 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-07-29 21:21 |
2楼的兄弟 ADD SP,10这条指令会不会还暗示了这个程序所定义的栈的大小10BIT呢?
如果这个栈大小没有受限制,超栈是很危险的!!!
------------------
回复:ADD SP,10 这句话什么意思??? | | |
|
|
|
|
[第18楼]
[ 回复时间:2011-07-31 14:35 ]
[引用]
[回复]
[ top ] | |
荣誉值:118
信誉值:0
注册日期:2011-07-07 22:59 |
把sp+10喽,也就是把栈空间加大一些,省的栈顶超界 | | |
|
|
|
|
[第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而不是其他? | | |
|
|
|
|
[第20楼]
[ 回复时间:2012-02-23 12:58 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2012-02-21 20:39 |
我们在后面对栈的操作会修改栈中的数据,不会影响到压入数据保存的状态吗? | | |
|
|
|
|
[第21楼]
[ 回复时间:2012-02-23 15:50 ]
[引用]
[回复]
[ top ] | |
荣誉值:405
信誉值:0
注册日期:2008-01-19 14:51 |
|
|
|
|
|
[第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中的值 所以程序出错。!
我是新手,刚学到这里,以上是我的理解,有错误的地方 还请指点 谢谢 | | |
|
|
|
|
[第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中的值 所以程序出错。!
我是新手,刚学到这里,以上是我的理解,有错误的地方 还请指点 谢谢 | | |
|
|
|
|
[第24楼]
[ 回复时间:2012-08-16 14:33 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2012-07-30 12:23 |
|
|
|
|
|
[第25楼]
[ 回复时间:2014-05-03 12:44 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2014-03-05 20:46 |
|
|
|
|
|
[第26楼]
[ 回复时间:2014-10-07 22:54 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2014-10-06 00:22 |
貌似中断用了12个字节,但为什么保护模式下恢复用了10个就可以了?剩下的一个字节有什么用吗?高手指点下。 | | |
|
|
|
|
[第27楼]
[ 回复时间:2015-05-18 09:53 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-03-16 22:48 |
|
|
|
|
|
[第28楼]
[ 回复时间:2015-10-13 11:00 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-01-17 12:29 |
用tr调试,就不会产生这个问题,debug的调试能力,还是弱了一点 | | |