|
主题 : : 实验8的精髓所在,好题!!! [待解决] |
回复[ 23次 ]
点击[ 1599次 ] | |
|
|
|
|
[帖 主]
[ 发表时间:2008-10-13 18:00 ]
[引用]
[回复]
[ top ] | |
荣誉值:2
信誉值:8
注册日期:2008-09-15 09:10 |
实验8程序
assume cs:codesg
codesg segment
mov ax,4c00H
int 21H
start:
mov ax,0
s:
nop
nop
mov di,offset s
mov si,offset s2
mov ax,cs:[si]
mov cs:[di],ax
s0:
jmp short s
s1:
mov ax,0
int 21H
mov ax,0
s2:
jmp short s1
nop
codesg ends
end start
个人愚见:
本程序的亮点就在于复制s2处的指令后,s处内存单元原先的两个nop 变为EBF6(即jmp short s1对应的机器码),关键就是EBF6的理解,容易产生错误的是:误解为S处的指令也为jmp short s1!!
正确的理解应是:F6是位移量!!!是补码形式,表示-10
当程序读取S处的指令后IP的值改为10,再执行指令,IP被修改成0,指向mov ax,4c00H ,这样程序就能正确返回了! | | |
|
|
|
|
[第1楼]
[ 回复时间:2008-10-14 10:51 ]
[引用]
[回复]
[ top ] | |
荣誉值:337
信誉值:0
注册日期:2008-01-01 17:48 |
第一次看到这个题,大多是人第一反应是怎么能执行呢:-)
不过动手分析一下,用debug跟踪一下就不一样了,经典案例!! | | |
|
|
|
|
[第2楼]
[ 回复时间:2008-11-06 16:00 ]
[引用]
[回复]
[ top ] | |
荣誉值:273
信誉值:0
注册日期:2008-01-23 20:23 |
很多就是被jmp的现象给误导了,以为是跟着标号地址跳呢,其实jmp是基于位移的,这个在编译后就确定了,如果光看标号找跳转的位置就惨了,当初这道题把我郁闷坏了。在走不出思维圈的时候,回头在温习一下书的讲解是非常有必要的。 | | |
|
|
|
|
[第3楼]
[ 回复时间:2008-11-10 16:31 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:2
注册日期:2008-09-06 21:01 |
|
|
|
|
|
[第4楼]
[ 回复时间:2008-11-13 15:53 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2007-11-06 14:36 |
呵呵,这个jmp 标号在编译后的机器码中,标号是位移,也就是说有正有负的,负的话就用补码表示,比如-10(十进制)的补码就是F6h,这个例子里的jmp short s1,其实就是jmp 0F6H,不规范的表示就是jmp -10,意思就是向上跳转到,向上移动10个字节的地方:
0000
0001
0002
0003
0004
0005
0006
0007
0008-0009-000A jmp -10
000A jmp将跳转到从这儿开始向上10个字节,0009,0008,0007……0001,0000,也就是跳转到0000处 | | |
|
|
|
|
[第5楼]
[ 回复时间:2008-11-14 14:44 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2008-11-14 14:37 |
我觉得如果如下弄能更好的理解,
s0:
jmp short s
s1:
mov ax, 0
int 021h
mov ax,0
mov ax,0
mov ax,0
mov ax,0
s2:
jmp short s1
nop
这样,因为当执行完jmp short s时,NOP地址中数据是EBED,偏移已经超出了此时有效代码段。
但是此时ip-偏移指向了垃圾地区,但是cpu还是跳转到了该垃圾区 | | |
|
|
|
|
[第6楼]
[ 回复时间:2008-11-17 22:28 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2007-10-17 09:53 |
|
|
|
|
|
[第7楼]
[ 回复时间:2008-12-22 17:02 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2008-12-06 21:24 |
个人认为这样更好理解一下:
S处复制的是EBF6,对于CPU来说,它并不认为这是一个JMP SHORT S1,它只是认为是JMP F6,也就是说IP被减去10,所以IP = ip - 10 =0,所以指令开始指向开始处执行。 | | |
|
|
|
|
[第8楼]
[ 回复时间:2008-12-23 19:18 ]
[引用]
[回复]
[ top ] | |
荣誉值:2
信誉值:8
注册日期:2008-09-15 09:10 |
|
|
|
|
|
[第9楼]
[ 回复时间:2009-02-13 14:08 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2007-09-11 07:13 |
就是理解不深刻 书上写了 是 按位移转移 不是 按标号 ,看也看见了,可是没理解 | | |
|
|
|
|
[第10楼]
[ 回复时间:2009-02-14 19:58 ]
[引用]
[回复]
[ top ] | |
荣誉值:2
信誉值:4
注册日期:2009-01-15 22:41 |
这个程序明白一点就ok,复制的是jmp short s1对应的机器码EBF6,而不是代码jmp short s1 本身。 | | |
|
|
|
|
[第11楼]
[ 回复时间:2009-02-14 20:00 ]
[引用]
[回复]
[ top ] | |
荣誉值:2
信誉值:4
注册日期:2009-01-15 22:41 |
部分机器码 ,一看即明白
13C4:0005 B80000 MOV AX,0000
13C4:0008 90 NOP
13C4:0009 90 NOP
13C4:000A BF0800 MOV DI,0008
13C4:000D BE2000 MOV SI,0020
13C4:0010 2E CS:
13C4:0011 8B04 MOV AX,[SI]
13C4:0013 2E CS:
13C4:0014 8905 MOV [DI],AX
13C4:0016 EBF0 JMP 0008
13C4:0018 B80000 MOV AX,0000
13C4:001B CD21 INT 21
13C4:001D B80000 MOV AX,0000
13C4:0020 EBF6 JMP 0018
13C4:0022 90 NOP
13C4:0023 B8C805 MOV AX,05C8 | | |
|
|
|
|
[第12楼]
[ 回复时间:2009-03-02 08:20 ]
[引用]
[回复]
[ top ] | |
荣誉值:2
信誉值:5
注册日期:2008-12-18 16:07 |
jmp 是只有转移的位移,没有目的地址,直接复制了数据,相当于等同的往回跳,哎!弄了半天 | | |
|
|
|
|
[第13楼]
[ 回复时间:2009-03-04 12:42 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-02-08 18:43 |
|
|
|
|
|
[第14楼]
[ 回复时间:2009-03-05 10:04 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2007-11-12 19:53 |
这个程序明白一点就ok,复制的是jmp short s1对应的机器码EBF6,而不是代码jmp short s1 本身。
------------------
回复:十分正确呵呵!~ | | |
|
|
|
|
[第15楼]
[ 回复时间:2011-06-15 02:15 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-05-16 07:53 |
|
|
|
|
|
[第16楼]
[ 回复时间:2011-07-01 12:40 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-01-17 12:29 |
|
|
|
|
|
[第17楼]
[ 回复时间:2012-01-26 02:18 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2012-01-10 21:29 |
仔细看了9.3搞明白了
主要是搞清楚带jmp 命令时的 (ip)的变化
执行机器码EBf6时是这样的,
先把EBF6读入指令缓冲器,此时(ip)=(ip)+2;指令EBF6的字节数
EBF6执行 此时(ip)=(ip)+2+(-10);F6的原码=ip-8
也就是说EBF6执行后,ip指向EBF6的上8个字节处指令 | | |
|
|
|
|
[第18楼]
[ 回复时间:2012-07-23 12:18 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:1
注册日期:2012-04-23 22:44 |
|
|
|
|
|
[第19楼]
[ 回复时间:2012-07-24 08:29 ]
[引用]
[回复]
[ top ] | |
荣誉值:30
信誉值:4
注册日期:2012-01-01 16:36 |
回复:[第18楼]
------------------
第2个nop指令的下一条指令的偏移地址是000AH
jmp short 标号,位移量已经被编译器编译成了00F6H (0EBF6H占2字节)
那么,把这个转移指令复制到两条nop指令处。
两条nop 变成了 0EBF6H 。
位移量是不变的,
那么,
000AH+00F6H=0
偏移地址变成了0。。所以指向了程序返回。
不懂的多多debug | | |
|
|
|
|
[第20楼]
[ 回复时间:2012-08-03 09:20 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-11-15 16:31 |
|
|
|
|
|
[第21楼]
[ 回复时间:2012-08-14 12:52 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2012-08-14 12:33 |
原来如此
s2处的jmp short s1位移后指向s1,执行程序后s处的jmp short s1位移后指向了mov ax,4c00h,他代码的距离直观上看是相等的。 | | |
|
|
|
|
[第22楼]
[ 回复时间:2012-08-20 09:40 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2012-08-14 17:57 |
指令被当作了数据处理,而后又被当作了指令执行。
------------------
回复:说的有深度,很经典!!学习了、 | | |
|
|
|
|
[第23楼]
[ 回复时间:2020-05-12 14:12 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2020-05-06 18:39 |
这样子s1到s2完这段内容没有被执行到对吗,因为执行的时候cs:ip从没有指到s1就返回了。 | | |