|
主题 : : 实验8程序分析 [待解决] |
回复[ 92次 ]
点击[ 5081次 ] | |
|
|
|
|
[帖 主]
[ 发表时间:2007-06-27 15:11 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2007-06-26 14:20 |
实验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
执行流程:
程序从start处 mov ax,0开始执行,执行到mov cs:[di],ax,就把s2:处jmp short s1拷贝到s处,即覆盖2个nop(正好2个字节)
jmp short s1 在s2处,可以计算一下需要往上编译10个字节(3(jmp short s1)+3*2(mov ax,0)+2(int 21H)),
debug可以看到机器码为ebf6,f6是补码,转换一下即10,也即是向上偏移10个字节,这样的话s:处的2个nop的代码修改成
ebf6。
程序接着往下运行,跑到s0:jmp short s,这样又s:处,执行EBF6,即往上偏移10字节,计算一下就知道,ip这个时候指向0,
跑到codesg段开始处,即执行mov ax,4c00H;int 21H | | |
|
|
|
|
[第1楼]
[ 回复时间:2007-08-01 19:43 ]
[引用]
[回复]
[ top ] | |
荣誉值:43
信誉值:3
注册日期:2007-07-05 19:53 |
|
|
|
|
|
[第2楼]
[ 回复时间:2007-08-27 18:44 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2007-08-26 17:25 |
|
|
|
|
|
[第3楼]
[ 回复时间:2007-09-17 21:58 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2007-09-04 14:41 |
|
|
|
|
|
[第4楼]
[ 回复时间:2007-10-05 10:12 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2007-09-04 14:41 |
可以计算一下需要往上编译10个字节(3(jmp short s1)+3*2(mov ax,0)+2(int 21H)),
3+3*2+2=11呀!?怎么回事? | | |
|
|
|
|
[第5楼]
[ 回复时间:2007-10-05 10:51 ]
[引用]
[回复]
[ top ] | |
荣誉值:50
信誉值:0
注册日期:2007-07-08 09:33 |
(3(jmp short s1)+3*2(mov ax,0)+2(int 21H)),
-----------------------
应该是楼主笔误吧;-)
jmp short s1是两个字节(jmp short s1拷贝到s处,即覆盖2个nop(2个字节))
jmp指令根据其对ip的修改范围不同而占字节数也不尽相同,比如jmp far ptr s占五个字节。 | | |
|
|
|
|
[第6楼]
[ 回复时间:2007-10-05 11:44 ]
[引用]
[回复]
[ top ] | |
荣誉值:106
信誉值:0
注册日期:2007-06-26 15:10 |
jmp short ,和 jmp near 都是将下一条指令的位置+偏移呵呵 | | |
|
|
|
|
[第7楼]
[ 回复时间:2007-10-11 17:47 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:2
注册日期:2007-10-08 10:36 |
|
|
|
|
|
[第8楼]
[ 回复时间:2007-10-11 18:56 ]
[引用]
[回复]
[ top ] | |
荣誉值:283
信誉值:0
注册日期:2007-06-26 11:42 |
不错!jmp跳转不是基于标号地址的,是基于偏移量的。树上的这个程序出的太经典了!这才叫“教书育人”呢!支持这样的好书! | | |
|
|
|
|
[第9楼]
[ 回复时间:2007-10-11 18:56 ]
[引用]
[回复]
[ top ] | |
荣誉值:283
信誉值:0
注册日期:2007-06-26 11:42 |
不好意思,写错了一个词“树上”改为“书上”。太激动了。呵呵 | | |
|
|
|
|
[第10楼]
[ 回复时间:2007-12-06 21:14 ]
[引用]
[回复]
[ top ] | |
荣誉值:1
信誉值:6
注册日期:2007-11-14 11:28 |
|
|
|
|
|
[第11楼]
[ 回复时间:2007-12-07 13:38 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2007-12-06 13:13 |
好啊,我开始时候还认为会是死循环,我没有想到回是这么处理的,太经典了(3(jmp short s1)+3*2(mov ax,0)+2(int 21H)), 一个nop站多少个字节啊 | | |
|
|
|
|
[第12楼]
[ 回复时间:2007-12-07 13:38 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2007-12-06 13:13 |
|
|
|
|
|
[第13楼]
[ 回复时间:2007-12-07 19:33 ]
[引用]
[回复]
[ top ] | |
荣誉值:32
信誉值:0
注册日期:2007-07-14 19:06 |
【回复】11楼:一个nop占多少个字节啊?
答:一个nop占一个字节。 | | |
|
|
|
|
[第14楼]
[ 回复时间:2007-12-15 17:19 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:1
注册日期:2007-12-07 22:42 |
牛人,太感谢了。看了程序半天没看懂,现在终于明白了。这个程序真是太好了,让我明白了好多。书是好书,楼主是好人. | | |
|
|
|
|
[第15楼]
[ 回复时间:2008-01-12 09:32 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2007-12-15 17:23 |
我在用masm编译的时候,
mov si,offset s2
出现问题:out of memory
没有生成obj文件
何解?? | | |
|
|
|
|
[第16楼]
[ 回复时间:2008-01-12 10:11 ]
[引用]
[回复]
[ top ] | |
荣誉值:472
信誉值:12
注册日期:2007-10-16 15:34 |
楼上的兄弟把程序写错了吧,把楼主的程序粘贴编译没有问题~
C:\masm>masm 0;
Microsoft (R) Macro Assembler Version 5.00
Copyright (C) Microsoft Corp 1981-1985, 1987. All rights reserved.
50712 + 450664 Bytes symbol space free
0 Warning Errors
0 Severe Errors
C:\masm> | | |
|
|
|
|
[第17楼]
[ 回复时间:2008-01-12 10:39 ]
[引用]
[回复]
[ top ] | |
荣誉值:50
信誉值:0
注册日期:2007-07-08 09:33 |
|
|
|
|
|
[第18楼]
[ 回复时间:2008-01-18 01:26 ]
[引用]
[回复]
[ top ] | |
荣誉值:3
信誉值:8
注册日期:2008-01-12 10:11 |
|
|
|
|
|
[第19楼]
[ 回复时间:2008-02-02 14:11 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2008-01-11 11:03 |
|
|
|
|
|
[第20楼]
[ 回复时间:2008-02-02 18:56 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2008-01-31 01:15 |
还是有点不明白哈~~~
可以计算一下需要往上编译10个字节(3(jmp short s1)+3*2(mov ax,0)+2(int 21H)),
这个是怎么计算的啊 | | |
|
|
|
|
[第21楼]
[ 回复时间:2008-02-14 13:12 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2008-01-23 14:48 |
我来贴一下莫去网名整理的答案,仅供大家参考:
在此题中较为深入地考察了‘段内直接短转移’[形如:jmp short 标号]的概念。
我们知道程序中:
mov di,offset s
mov si,offset s2
mov ax,cs:[si]
mov cs:[di],ax
四条指令的作用是将标号s2处的一条指令复制到标号s处。这时我们应该关心所复制的语句"jmp short s1"对程序的影响:我们知道在段内直接短转移指令所对应的机器码中,并不包含转移的目的地址,而包含的是转移的位移量(如对此概念还不太熟悉,请查看书中第167页的内容)。也就是说,在源程序的编译过程中,编译器遇到‘段内直接短转移’[形如:jmp short 标号]时就会自动算出其要跳转的位移量,以便程序在执行‘段内直接短转移’的指令时就根据位移量进行(向前或向后)跳转。通过调试中的U命令我们可以看到指令's2:jmp short s1'所对应的机器码是EBF6,F6h(-10d的补码)就是跳转的位移量[此位移量也可由指令's2:jmp short s1'处的偏移地址18h减去指令's2:jmp short s1'后一个字节的偏移地址22h得出]。这时我们就知道了其实复制到标号s处的指令所对应的机器码就是EBF6(刚好取代两个nop所对应的机器码),它的作用就是将当前IP向前移动10个字节。当程序执行标号s0处的指令后,程序便跳到标号s处接着执行标号s处的指令。s处的指令的作用是向前跳10字节,于是便跳到了代码中的第一条指令,继续执行后便实现了程序的正常返回。
[注意:此程序不会也不可能执行标号s1处后的指令。] | | |
|
|
|
|
[第22楼]
[ 回复时间:2008-02-14 13:13 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2008-01-23 14:48 |
|
|
|
|
|
[第23楼]
[ 回复时间:2008-02-17 21:34 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2008-02-14 15:50 |
|
|
|
|
|
[第24楼]
[ 回复时间:2008-02-25 18:10 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2007-12-11 10:23 |
其实这个实验有两个最关键的关键点:
1。“jmp short 标号”的原理。
2。程序是编译后才运行的。
理解清楚了这两点就什么都好办了。 | | |
|
|
|
|
[第25楼]
[ 回复时间:2008-02-26 11:39 ]
[引用]
[回复]
[ top ] | |
荣誉值:106
信誉值:0
注册日期:2007-06-26 15:10 |
jmp跳转不是基于标号地址的,是基于偏移量的------是这么回事 | | |
|
|
|
|
[第26楼]
[ 回复时间:2008-02-29 10:22 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2008-02-15 17:02 |
|
|
|
|
|
[第27楼]
[ 回复时间:2008-04-12 10:12 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:6
注册日期:2007-12-18 19:12 |
|
|
|
|
|
[第28楼]
[ 回复时间:2008-05-21 17:58 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:16
注册日期:2008-03-17 20:21 |
|
|
|
|
|
[第29楼]
[ 回复时间:2008-06-27 22:28 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2008-05-30 11:10 |
|
|
|
|
|
[第30楼]
[ 回复时间:2008-07-29 14:22 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2008-07-03 16:13 |
|
|
|
|
|
[第31楼]
[ 回复时间:2008-08-03 13:01 ]
[引用]
[回复]
[ top ] | |
荣誉值:2
信誉值:0
注册日期:2008-07-06 17:24 |
|
|
|
|
|
[第32楼]
[ 回复时间:2008-08-22 17:50 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2008-01-03 14:54 |
|
|
|
|
|
[第33楼]
[ 回复时间:2008-08-25 15:56 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2008-08-01 10:20 |
|
|
|
|
|
[第34楼]
[ 回复时间:2009-05-10 11:50 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-03-25 19:19 |
我在用masm编译的时候,
mov si,offset s2
出现问题:out of memory
没有生成obj文件
何解??
------------------
回复:逗号不对,, | | |
|
|
|
|
[第35楼]
[ 回复时间:2009-05-30 01:00 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-05-30 00:49 |
分析得很好,
从这个程序中我认为短转移指令在内存中最好不要移动,
这样造成不好读程序。
不知道实战中是怎么做 | | |
|
|
|
|
[第36楼]
[ 回复时间:2009-10-16 00:45 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-10-12 11:31 |
做了才知道自己理解这么的浅,,得细看了,,,谢谢啊 | | |
|
|
|
|
[第37楼]
[ 回复时间:2009-10-24 11:32 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2008-10-18 00:34 |
指令's2:jmp short s1'处的偏移地址18h减去指令's2:jmp short s1'后一个字节的偏移地址22h
18H-22H=-0AH 的意思就是向前移动10个字节么 | | |
|
|
|
|
[第38楼]
[ 回复时间:2009-12-06 20:20 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-10-20 21:58 |
|
|
|
|
|
[第39楼]
[ 回复时间:2009-12-12 15:17 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:6
注册日期:2008-10-12 21:48 |
拷贝jmp short s1 覆盖两个nop的时候,其实"s1"已经不存在了,已经被换成s2和s1之间的“相对位移”了,我觉得是这个程序的关键。 | | |
|
|
|
|
[第40楼]
[ 回复时间:2009-12-15 10:43 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-11-13 21:36 |
|
|
|
|
|
[第41楼]
[ 回复时间:2010-01-12 14:53 ]
[引用]
[回复]
[ top ] | |
荣誉值:6
信誉值:0
注册日期:2009-12-18 19:53 |
学习呀,自己仔细看了一下,开始也不懂,新手就是新手啊,终于明白道道了
-u
0B62:0005 B80000 MOV AX,0000
0B62:0008 90 NOP
0B62:0009 90 NOP
0B62:000A BF0800 MOV DI,0008
0B62:000D BE2000 MOV SI,0020
0B62:0010 2E CS:
0B62:0011 8B04 MOV AX,[SI]
0B62:0013 2E CS:
0B62:0014 8905 MOV [DI],AX
0B62:0016 EBF0 JMP 0008
0B62:0018 B80000 MOV AX,0000
0B62:001B CD21 INT 21
0B62:001D B80000 MOV AX,0000
0B62:0020 EBF6 JMP 0018
0B62:0022 90 NOP
0B62:0023 54 PUSH SP
0B62:0024 0C2B OR AL,2B
其实就是0020h和0018h之间的位移,20h就是32,18h就是24,位移为8 按书上计算应该是10,加上两个字节
从理解上来说,从具体位置上理解为8也行,
然后跳转到0008,执行,向前移8位变为0000
哎。。笨啊。。
-g 0010 | | |
|
|
|
|
[第42楼]
[ 回复时间:2010-01-22 17:23 ]
[引用]
[回复]
[ top ] | |
荣誉值:4
信誉值:6
注册日期:2010-01-07 10:37 |
|
|
|
|
|
[第43楼]
[ 回复时间:2010-03-17 15:54 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-11-16 22:21 |
|
|
|
|
|
[第44楼]
[ 回复时间:2010-03-23 16:56 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-01-20 21:20 |
有一点想不通,那41楼的来说
0B62:0016 EBF0 JMP 0008
FO的补码是10H,就是向上数16位到0B62:0008
可是0016-0008=E,E=14
还差了2个。
如果8,9,A,B,C,D,E,F,10,11,12,13,14,15,16数也只有15个。还有一个跑哪去了! | | |
|
|
|
|
[第45楼]
[ 回复时间:2010-03-23 19:02 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-01-02 17:21 |
LS的 你问的问题已经被以各种形式问过N遍了 好吧 第N+1此回答一下
因为8086CPU取指令的特点是 先把指令取到缓存中 然后IP就指向下一条指令的起始地址
也就是 在执行 0B62:0016 EBF0 JMP 0008之前
IP=0018 也就是指向下一条指令的地址
此时再计算IP与0008之间的差 即0018-0008=10
其反码就是F0 | | |
|
|
|
|
[第46楼]
[ 回复时间:2010-03-23 19:05 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-01-02 17:21 |
晕 上面都少打了个H 应该是0018H-0008H=10H 其反码是F0H | | |
|
|
|
|
[第47楼]
[ 回复时间:2010-03-29 19:22 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:2
注册日期:2010-03-05 21:31 |
看了好长时间,一直看不懂,原来是这样的啊,山重水复疑无路,柳暗花明又一村,经典! | | |
|
|
|
|
[第48楼]
[ 回复时间:2010-03-30 22:18 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-03-27 09:11 |
确实经典!不过再仔细想一下,代码开头处S0处应该只有8个字节呀,而跳转位移是10个字节。这是不是又值得我们思考:当IP所指位置超出代码段(在这里是超出代码头即CS:00处),是不是IP会自动只指向代码头呢?还望牛人指点迷津呀 | | |
|
|
|
|
[第49楼]
[ 回复时间:2010-03-30 22:18 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-03-27 09:11 |
回复:[贴 主]
------------------
确实经典!不过再仔细想一下,代码开头处离S0处应该只有8个字节呀,而跳转位移是10个字节。这是不是又值得我们思考:当IP所指位置超出代码段(在这里是超出代码头即CS:00处),是不是IP会自动只指向代码头呢?还望牛人指点迷津呀 | | |
|
|
|
|
[第50楼]
[ 回复时间:2010-04-27 23:15 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-04-26 15:09 |
呵呵 ,07年的帖子等到10年了 ,看来大家的学习热情一直没减过啊 | | |
|
|
|
|
[第51楼]
[ 回复时间:2010-05-05 20:47 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-12-01 09:12 |
|
|
|
|
|
[第52楼]
[ 回复时间:2010-06-10 16:03 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-06-03 14:15 |
21楼厉害,直接提刀就往肉上砍!
我感觉这个试验题最主要一点在于编译器将jmp指令编译后就已经把将要偏移的位移量计算出来并存储在了机器码中了,而当执行给标号S处传值(即传递机器码)时,里面的位移量已经被确定了。 | | |
|
|
|
|
[第53楼]
[ 回复时间:2010-06-11 21:46 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-05-17 21:22 |
|
|
|
|
|
[第54楼]
[ 回复时间:2010-07-09 22:33 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-04-01 11:56 |
|
|
|
|
|
[第55楼]
[ 回复时间:2010-07-17 23:48 ]
[引用]
[回复]
[ top ] | |
荣誉值:3
信誉值:0
注册日期:2008-06-04 16:24 |
回复49楼的兄弟
确实经典!不过再仔细想一下,代码开头处离S0处应该只有8个字节呀,而跳转位移是10个字节。这是不是又值得我们思考:当IP所指位置超出代码段(在这里是超出代码头即CS:00处),是不是IP会自动只指向代码头呢?还望牛人指点迷津呀
------------------
回复:
当 cs:0008处是 EBF6时 你可以这样理解
偏移地址 机器码 汇编指令
0008 EBF6 jmp x ,
000A mov di,offset s
标号的地址=8位位移+JMP指令后的第一个字节的地址(JMP指令后的第一个字节的地址是000A即:10)所以得出:
X=-10+10=0 | | |
|
|
|
|
[第56楼]
[ 回复时间:2010-07-18 01:02 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:6
注册日期:2010-07-13 10:33 |
重新复制下代码【比较好看……
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
不觉得框起来的部分很像么? | | |
|
|
|
|
[第57楼]
[ 回复时间:2010-07-23 08:57 ]
[引用]
[回复]
[ top ] | |
荣誉值:9
信誉值:3
注册日期:2008-06-12 09:16 |
重新复制下代码【比较好看……
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
不觉得框起来的部分很像么?
------------------
回复:不觉得,因为s1标号处后面的指令压根儿就没有执行,因此,只要jmp short s1指令不变且保持向前偏移10字节,s1后面的指令可以随便变动,对本程序的执行基本上没哟什么影响。 | | |
|
|
|
|
[第58楼]
[ 回复时间:2010-08-15 01:06 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-07-04 09:59 |
|
|
|
|
|
[第59楼]
[ 回复时间:2010-09-03 13:30 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-09-03 12:59 |
代码开头处离S0处应该只有8个字节呀,而跳转位移是10个字节。这是不是又值得我们思考:当IP所指位置超出代码段(在这里是超出代码头即CS:00处),是不是IP会自动只指向代码头呢?还望牛人指点迷津呀!这个问题问的好,正是我所想问的,我亲自调试了一下,发现jmp short s之后,IP= 0008H,然后向前移动10个字节?这不明显超出代码段了?这个问题又如何解释呢?看了楼上面的各位的回答,大部分人都没发现这个问题,真是可笑。 | | |
|
|
|
|
[第60楼]
[ 回复时间:2010-09-03 14:23 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-09-03 12:59 |
对不起,刚才生气了发的帖子让大家见笑了。
这里我来给大家回答一下这个问题吧,相信大家 仔细看还是能看出楼上问题的。
一步一步的跟踪结果:
0B58:0016 EBF0 JMP 0008H
0B58:0008H EBF6 JMP 0000 (我自己电脑中的数据)
0B58:0000 B8004C MOV AX,4C00
从这里开始分析,首先IP=16H(16进制)
此时细节如下:1。从IP=0016H中取指令,然后IP=IP+2(指令长度,不罗嗦)
2。此时IP执行0018H,
3。CPU执行 EBF0 则 IP=18H-16=8(注意F0是-16的补码,16是10进制,注意这里)
此时IP=0008H
然后从0008H中取指令,此时的指令为S2处的指令,前面4条指令已经把覆盖过了,这里的指令为JMP SHORT S1
他其实已经把S处的NOP NOP两个字节给覆盖了。
然后IP=IP+2(指令长度)=000AH
然后执行指令 EBF6 都知道F6是-10的补码,则IP=000AH-10(10进制,别糊涂了)=0H
则此时IP=0,也就是第一条指令的位置。OK,完毕!大家在琢磨琢磨吧! | | |
|
|
|
|
[第61楼]
[ 回复时间:2011-06-15 02:15 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-05-16 07:53 |
|
|
|
|
|
[第62楼]
[ 回复时间:2011-08-21 00:05 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-05-10 18:51 |
妙哉!
此题思路奇特。
学汇编不能只看表面助记符的意思,要多注意机器码代表的什么意思。 | | |
|
|
|
|
[第63楼]
[ 回复时间:2011-09-29 09:00 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-09-23 17:33 |
|
|
|
|
|
[第64楼]
[ 回复时间:2011-09-29 09:01 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-09-23 17:33 |
|
|
|
|
|
[第65楼]
[ 回复时间:2011-10-03 16:31 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-10-03 16:25 |
小弟不才,才开始学汇编,不过我也为这个题头晕过!可是我的理解和大家不同,大家误喷!大家其实不用逐字逐句的分析,王爽老师讲过有关JMP的位移分析,大家有没注意到,只要是跳转,都有一个EB **的这个机器指令,你用debug里的u命令查一下机器码,会发现这个EB到了JMP 0000上去了,而mov ax,4c00h里面的偏移地址正好是0,所以是可以正确返回的! | | |
|
|
|
|
[第66楼]
[ 回复时间:2011-10-03 19:04 ]
[引用]
[回复]
[ top ] | |
荣誉值:118
信誉值:0
注册日期:2011-07-07 22:59 |
楼上说的不对,书上说了,是根据8位位移量进行跳转的,负数是向上,正数向下。 | | |
|
|
|
|
[第67楼]
[ 回复时间:2011-10-07 18:36 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-08-18 06:18 |
|
|
|
|
|
[第68楼]
[ 回复时间:2011-10-10 14:08 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-10-10 14:03 |
ip更新是指令执行之前进行的,在最后那一步指令被cpu执行之前,ip已经更新+2了,所以往上走10字节刚好指向mov ax,4c00H | | |
|
|
|
|
[第69楼]
[ 回复时间:2011-10-25 17:17 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-10-11 13:41 |
|
|
|
|
|
[第70楼]
[ 回复时间:2011-11-05 16:35 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-11-03 19:04 |
assume cs:code
code segment
mov ah,4ch
int 21h
start: mov ax,0
nop ;add a nop here!!!!
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
code ends
end start
我的程序是这样的,加了一个nop才能有“Program terminated normally”的结果!!!
说实话………… | | |
|
|
|
|
[第71楼]
[ 回复时间:2011-11-05 16:38 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-11-03 19:04 |
|
|
|
|
|
[第72楼]
[ 回复时间:2011-12-06 15:03 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-10-10 23:00 |
|
|
|
|
|
[第73楼]
[ 回复时间:2011-12-21 14:33 ]
[引用]
[回复]
[ top ] | |
荣誉值:4
信誉值:4
注册日期:2011-12-05 18:50 |
原来是借用了S2》S1的偏移值,也就是说偏移量的值在编译时是计算好的。在程序运行时,值是不变的!! | | |
|
|
|
|
[第74楼]
[ 回复时间:2011-12-21 14:36 ]
[引用]
[回复]
[ top ] | |
荣誉值:4
信誉值:4
注册日期:2011-12-05 18:50 |
|
|
|
|
|
[第75楼]
[ 回复时间:2011-12-21 14:37 ]
[引用]
[回复]
[ top ] | |
荣誉值:4
信誉值:4
注册日期:2011-12-05 18:50 |
|
|
|
|
|
[第76楼]
[ 回复时间:2012-02-08 17:12 ]
[引用]
[回复]
[ top ] | |
荣誉值:6
信誉值:0
注册日期:2012-01-03 21:14 |
回复:[第60楼]
------------------
领悟中。。。。。 | | |
|
|
|
|
[第77楼]
[ 回复时间:2012-03-19 23:13 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-04-06 22:45 |
|
|
|
|
|
[第78楼]
[ 回复时间:2012-03-19 23:13 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-04-06 22:45 |
|
|
|
|
|
[第79楼]
[ 回复时间:2012-03-19 23:13 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-04-06 22:45 |
|
|
|
|
|
[第80楼]
[ 回复时间:2012-03-20 16:06 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2012-03-12 11:03 |
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
现在有三个问题:mov di,offset s
mov si,offset s2
mov ax,cs:[si]
mov cs:[di],ax
这几句话是将EBF6 给复制到两个nop 问题是EBF6被机器解码时为 jmp 0018 为什么复制过去就变成了 jmp 0000 了。这是一个偏移量,可为什么变了呢。第二机器如何知道EBF6中F6是一个补码,不是自己算一下吧。
第三个问题 EBF6意思是向前偏移10个字节,在nop时当时的地址为0b8b:0008和0b8b:0009这二个字节中,如果向前偏移10字节的话岂不是越过代码首址了,除非这样执行的,就是先执行这句话,执行后之后IP自动变为 000A,理论上是这样的,只是我的猜 想,以上三个问题很是不解。尤其是第一个。请哪位高手给我解答一下,谢谢了。 | | |
|
|
|
|
[第81楼]
[ 回复时间:2012-03-30 13:12 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:5
注册日期:2012-03-22 15:34 |
回复:[第80楼]
------------------
第一个问题,复制的时候不是复制我们所见到的语句,这里不是复制jmp 0018,而是复制它的机器码过去,机器码在这里的意思是向上跳10位。
第二个问题我也不是很清楚,但是我自己理解应该是计算机默认的。
第三个问题你的猜想是对的,在执行jmp之前,ip已经指向了下一句,所以000A跳到0000就执行第一句话了。 | | |
|
|
|
|
[第82楼]
[ 回复时间:2012-08-20 10:38 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2012-08-14 17:57 |
|
|
|
|
|
[第83楼]
[ 回复时间:2012-09-01 11:42 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2012-04-07 22:11 |
胡说八道,第一楼根本没有仔细观察运行步骤!
运行mov cs:[di],ax时,就改写了s: nop的空指令(null)成EBF6。------------|
nop |
请注意EBF6机器码在这里的意思是向上跳9位 ,绝对不是向上跳10位! |
!
"s0:jmp short s"机器码指令是EBF9,在这里的意思是向上跳6位!回数正好在s:nop处!此时s的内存机器代码是EBF6,意思是向上跳6位后又向上跳9位!问题是再往上跳就出现转移位移出界,但编绎器没有警告就跳到mov ax,4c00h 为什么? | | |
|
|
|
|
[第84楼]
[ 回复时间:2012-09-05 17:13 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2012-08-25 20:51 |
回复:[第83楼]
------------------
为什么不是跳10位?F6补码是-10,就是向上跳10位正好是mov ax,4c00h啊。
你自己不想想清楚就说别人胡说八道,这不太好吧。 | | |
|
|
|
|
[第85楼]
[ 回复时间:2012-09-26 14:56 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2012-09-26 11:24 |
我觉得这个是不是给我一个启示,如何控制jmp指令,实现跳出循环? | | |
|
|
|
|
[第86楼]
[ 回复时间:2012-10-02 21:58 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2012-09-30 22:11 |
(3(jmp short s1)+3*2(mov ax,0)+2(int 21H)),
-----------------------
应该是楼主笔误吧;-)
jmp short s1是两个字节(jmp short s1拷贝到s处,即覆盖2个nop(2个字节))
jmp指令根据其对ip的修改范围不同而占字节数也不尽相同,比如jmp far ptr s占五个字节。
------------------
回复:jmp far ptr s不是应该是四个字节么? | | |
|
|
|
|
[第87楼]
[ 回复时间:2012-10-14 22:07 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2012-10-14 19:42 |
记住 是jmp指令 后 后 后 的第一个字节 nop nop 换成ebf6 enf6本身也占2个字节 所以加上前面的 3+2+3个字节 共10个字节了 ok | | |
|
|
|
|
[第88楼]
[ 回复时间:2012-10-14 22:08 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2012-10-14 19:42 |
记住 是jmp指令 后 后 后 的第一个字节 nop nop 换成ebf6 enf6本身也占2个字节 所以加上前面的 3+2+3个字节 共10个字节了 ok | | |
|
|
|
|
[第89楼]
[ 回复时间:2012-11-07 23:57 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2012-01-01 20:45 |
刚开始,看也是有点混,但是后来用DEBUG调试了一下,就什么都明白了,看来还得加点劲 | | |
|
|
|
|
[第90楼]
[ 回复时间:2014-07-11 18:08 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2014-07-11 18:04 |
分析的很好,我上初中的时候你们发了这个帖子,现在我大二了,哈哈。 | | |
|
|
|
|
[第91楼]
[ 回复时间:2014-08-06 10:25 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2012-08-27 13:18 |
|
|
|
|
|
[第92楼]
[ 回复时间:2017-11-28 04:37 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2017-01-24 04:03 |
顶,有点明白了,不太懂为什么mov 内存单元,另一个内存单元,
会把另一个内存单元的代码复制到内存单元中,不是地址吗 | | |