. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
刷新 | 提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->转移指令的原理
  管理员: assembly   [回复本贴] [收藏本贴] [管理本贴] [关闭窗口]
主题 : :  实验8程序分析  [待解决] 回复[ 92次 ]   点击[ 5081次 ]  
newasmer
[帖 主]   [ 发表时间: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
Wednesday
[第1楼]   [ 回复时间:2007-08-01 19:43 ]   [引用]   [回复]   [ top ] 
荣誉值:43
信誉值:3
注册日期:2007-07-05 19:53
分析正确,很好。
shenrz
[第2楼]   [ 回复时间:2007-08-27 18:44 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2007-08-26 17:25
顶...
jznhljg
[第3楼]   [ 回复时间:2007-09-17 21:58 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2007-09-04 14:41
太有才了...
jznhljg
[第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呀!?怎么回事?
zhuzhu
[第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占五个字节。
sunshine
[第6楼]   [ 回复时间:2007-10-05 11:44 ]   [引用]   [回复]   [ top ] 
荣誉值:106
信誉值:0
注册日期:2007-06-26 15:10
jmp short ,和 jmp near 都是将下一条指令的位置+偏移呵呵
linuxembedded
[第7楼]   [ 回复时间:2007-10-11 17:47 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:2
注册日期:2007-10-08 10:36
分析的有理~
对头
fishboy
[第8楼]   [ 回复时间:2007-10-11 18:56 ]   [引用]   [回复]   [ top ] 
荣誉值:283
信誉值:0
注册日期:2007-06-26 11:42
不错!jmp跳转不是基于标号地址的,是基于偏移量的。树上的这个程序出的太经典了!这才叫“教书育人”呢!支持这样的好书!
fishboy
[第9楼]   [ 回复时间:2007-10-11 18:56 ]   [引用]   [回复]   [ top ] 
荣誉值:283
信誉值:0
注册日期:2007-06-26 11:42
不好意思,写错了一个词“树上”改为“书上”。太激动了。呵呵
cdzjf
[第10楼]   [ 回复时间:2007-12-06 21:14 ]   [引用]   [回复]   [ top ] 
荣誉值:1
信誉值:6
注册日期:2007-11-14 11:28
呵呵
fengbangyue
[第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站多少个字节啊
fengbangyue
[第12楼]   [ 回复时间:2007-12-07 13:38 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2007-12-06 13:13
我太惭愧了啊,还什么都不知道
happy
[第13楼]   [ 回复时间:2007-12-07 19:33 ]   [引用]   [回复]   [ top ] 
荣誉值:32
信誉值:0
注册日期:2007-07-14 19:06
【回复】11楼:一个nop占多少个字节啊?
答:一个nop占一个字节。
zengbo_han
[第14楼]   [ 回复时间:2007-12-15 17:19 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:1
注册日期:2007-12-07 22:42
牛人,太感谢了。看了程序半天没看懂,现在终于明白了。这个程序真是太好了,让我明白了好多。书是好书,楼主是好人.
huadong
[第15楼]   [ 回复时间:2008-01-12 09:32 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2007-12-15 17:23
我在用masm编译的时候, 
mov si,offset s2 
出现问题:out of memory
没有生成obj文件
何解??
mouse
[第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>
zhuzhu
[第17楼]   [ 回复时间:2008-01-12 10:39 ]   [引用]   [回复]   [ top ] 
荣誉值:50
信誉值:0
注册日期:2007-07-08 09:33
15楼兄弟可以把代码发过来大家看看~
zkkpkk
[第18楼]   [ 回复时间:2008-01-18 01:26 ]   [引用]   [回复]   [ top ] 
荣誉值:3
信誉值:8
注册日期:2008-01-12 10:11
利用了debug只认机器码
qing4555
[第19楼]   [ 回复时间:2008-02-02 14:11 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2008-01-11 11:03
看了好几遍,终于明白了.
locate
[第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)), 
这个是怎么计算的啊
txltian
[第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处后的指令。]
txltian
[第22楼]   [ 回复时间:2008-02-14 13:13 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2008-01-23 14:48
莫取网名
sabrina
[第23楼]   [ 回复时间:2008-02-17 21:34 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2008-02-14 15:50
好文章 ,顶一下!
lyman
[第24楼]   [ 回复时间:2008-02-25 18:10 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2007-12-11 10:23
其实这个实验有两个最关键的关键点:
1。“jmp short 标号”的原理。
2。程序是编译后才运行的。
理解清楚了这两点就什么都好办了。
sunshine
[第25楼]   [ 回复时间:2008-02-26 11:39 ]   [引用]   [回复]   [ top ] 
荣誉值:106
信誉值:0
注册日期:2007-06-26 15:10
jmp跳转不是基于标号地址的,是基于偏移量的------是这么回事
guoxyj
[第26楼]   [ 回复时间:2008-02-29 10:22 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2008-02-15 17:02
真不一般的强
aaa2117
[第27楼]   [ 回复时间:2008-04-12 10:12 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:6
注册日期:2007-12-18 19:12
牛人,太感谢了。
debugkkk
[第28楼]   [ 回复时间:2008-05-21 17:58 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:16
注册日期:2008-03-17 20:21
厉害,想了半天,你们真牛。。。
zgl80438989
[第29楼]   [ 回复时间:2008-06-27 22:28 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2008-05-30 11:10
I see
zzxjypm
[第30楼]   [ 回复时间:2008-07-29 14:22 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2008-07-03 16:13
都不是一般的高手呢。。。正解
sbx2000_0
[第31楼]   [ 回复时间:2008-08-03 13:01 ]   [引用]   [回复]   [ top ] 
荣誉值:2
信誉值:0
注册日期:2008-07-06 17:24
各位真的好强!果然都是高手!
usingnamespacestd
[第32楼]   [ 回复时间:2008-08-22 17:50 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2008-01-03 14:54
支持,呵呵
rtianhua
[第33楼]   [ 回复时间:2008-08-25 15:56 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2008-08-01 10:20
书看的可真细呀
zpd1976
[第34楼]   [ 回复时间:2009-05-10 11:50 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-03-25 19:19
我在用masm编译的时候, 
mov si,offset s2 
出现问题:out of memory
没有生成obj文件
何解??
------------------
回复:逗号不对,,
chengshun158
[第35楼]   [ 回复时间:2009-05-30 01:00 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-05-30 00:49
分析得很好,
从这个程序中我认为短转移指令在内存中最好不要移动,
这样造成不好读程序。
不知道实战中是怎么做
h8312
[第36楼]   [ 回复时间:2009-10-16 00:45 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-10-12 11:31
做了才知道自己理解这么的浅,,得细看了,,,谢谢啊
qingfeng203
[第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个字节么
liuwenzhonghgz
[第38楼]   [ 回复时间:2009-12-06 20:20 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-10-20 21:58
呵呵就是电脑再鬼也鬼不过人呀
ycshjl
[第39楼]   [ 回复时间:2009-12-12 15:17 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:6
注册日期:2008-10-12 21:48
拷贝jmp short s1 覆盖两个nop的时候,其实"s1"已经不存在了,已经被换成s2和s1之间的“相对位移”了,我觉得是这个程序的关键。
avenue
[第40楼]   [ 回复时间:2009-12-15 10:43 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-11-13 21:36
强悍!
ldlihuanfa
[第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
qiangzi
[第42楼]   [ 回复时间:2010-01-22 17:23 ]   [引用]   [回复]   [ top ] 
荣誉值:4
信誉值:6
注册日期:2010-01-07 10:37
必须的要顶啊
hhy0504
[第43楼]   [ 回复时间:2010-03-17 15:54 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-11-16 22:21
楼主 牛人!
qiyu2580
[第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个。还有一个跑哪去了!
ailesargentees
[第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
ailesargentees
[第46楼]   [ 回复时间:2010-03-23 19:05 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2010-01-02 17:21
晕 上面都少打了个H 应该是0018H-0008H=10H 其反码是F0H
feixiang135790
[第47楼]   [ 回复时间:2010-03-29 19:22 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:2
注册日期:2010-03-05 21:31
看了好长时间,一直看不懂,原来是这样的啊,山重水复疑无路,柳暗花明又一村,经典!
ddup
[第48楼]   [ 回复时间:2010-03-30 22:18 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2010-03-27 09:11
确实经典!不过再仔细想一下,代码开头处S0处应该只有8个字节呀,而跳转位移是10个字节。这是不是又值得我们思考:当IP所指位置超出代码段(在这里是超出代码头即CS:00处),是不是IP会自动只指向代码头呢?还望牛人指点迷津呀
ddup
[第49楼]   [ 回复时间:2010-03-30 22:18 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2010-03-27 09:11
回复:[贴 主]
------------------
确实经典!不过再仔细想一下,代码开头处离S0处应该只有8个字节呀,而跳转位移是10个字节。这是不是又值得我们思考:当IP所指位置超出代码段(在这里是超出代码头即CS:00处),是不是IP会自动只指向代码头呢?还望牛人指点迷津呀
tink_tink
[第50楼]   [ 回复时间:2010-04-27 23:15 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2010-04-26 15:09
呵呵 ,07年的帖子等到10年了 ,看来大家的学习热情一直没减过啊
zhouxiao
[第51楼]   [ 回复时间:2010-05-05 20:47 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-12-01 09:12
高手
我看了很久,就是看不出来怎么回事
mawentao728
[第52楼]   [ 回复时间:2010-06-10 16:03 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2010-06-03 14:15
21楼厉害,直接提刀就往肉上砍!
我感觉这个试验题最主要一点在于编译器将jmp指令编译后就已经把将要偏移的位移量计算出来并存储在了机器码中了,而当执行给标号S处传值(即传递机器码)时,里面的位移量已经被确定了。
392271275
[第53楼]   [ 回复时间:2010-06-11 21:46 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2010-05-17 21:22
茅塞顿开!!
01178
[第54楼]   [ 回复时间:2010-07-09 22:33 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2010-04-01 11:56
你们都是牛人啊.佩服!
till
[第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
imandry
[第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 

不觉得框起来的部分很像么?
towersimper
[第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后面的指令可以随便变动,对本程序的执行基本上没哟什么影响。
454812511
[第58楼]   [ 回复时间:2010-08-15 01:06 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2010-07-04 09:59
是8个字节
yiruirui
[第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个字节?这不明显超出代码段了?这个问题又如何解释呢?看了楼上面的各位的回答,大部分人都没发现这个问题,真是可笑。
yiruirui
[第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,完毕!大家在琢磨琢磨吧!
frogoscar
[第61楼]   [ 回复时间:2011-06-15 02:15 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-05-16 07:53
好题,那时也没理解,还好这边有高人~~~~~~~
next_soul
[第62楼]   [ 回复时间:2011-08-21 00:05 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-05-10 18:51
妙哉!
此题思路奇特。
学汇编不能只看表面助记符的意思,要多注意机器码代表的什么意思。
may86463343
[第63楼]   [ 回复时间:2011-09-29 09:00 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-09-23 17:33
高手不是一般的多
may86463343
[第64楼]   [ 回复时间:2011-09-29 09:01 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-09-23 17:33
顶62楼,说的没错
qq67656467
[第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,所以是可以正确返回的!
chinatree
[第66楼]   [ 回复时间:2011-10-03 19:04 ]   [引用]   [回复]   [ top ] 
荣誉值:118
信誉值:0
注册日期:2011-07-07 22:59
楼上说的不对,书上说了,是根据8位位移量进行跳转的,负数是向上,正数向下。
minidxer
[第67楼]   [ 回复时间:2011-10-07 18:36 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-08-18 06:18
Mark
zmer
[第68楼]   [ 回复时间:2011-10-10 14:08 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-10-10 14:03
ip更新是指令执行之前进行的,在最后那一步指令被cpu执行之前,ip已经更新+2了,所以往上走10字节刚好指向mov ax,4c00H
xflfc
[第69楼]   [ 回复时间:2011-10-25 17:17 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-10-11 13:41
好手不是一般的多
fomalhaut
[第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”的结果!!!
说实话…………
fomalhaut
[第71楼]   [ 回复时间:2011-11-05 16:38 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-11-03 19:04
啊,我知道错在哪里了!!
惭愧
twozs
[第72楼]   [ 回复时间:2011-12-06 15:03 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-10-10 23:00
恩,分析的不错,顶一个
donqy
[第73楼]   [ 回复时间:2011-12-21 14:33 ]   [引用]   [回复]   [ top ] 
荣誉值:4
信誉值:4
注册日期:2011-12-05 18:50
原来是借用了S2》S1的偏移值,也就是说偏移量的值在编译时是计算好的。在程序运行时,值是不变的!!
donqy
[第74楼]   [ 回复时间:2011-12-21 14:36 ]   [引用]   [回复]   [ top ] 
荣誉值:4
信誉值:4
注册日期:2011-12-05 18:50
我觉得这应当叫作“静态编译”吧
donqy
[第75楼]   [ 回复时间:2011-12-21 14:37 ]   [引用]   [回复]   [ top ] 
荣誉值:4
信誉值:4
注册日期:2011-12-05 18:50
等咱学好了,给出个动态的,应该就没那么意料之外了
ministar
[第76楼]   [ 回复时间:2012-02-08 17:12 ]   [引用]   [回复]   [ top ] 
荣誉值:6
信誉值:0
注册日期:2012-01-03 21:14
回复:[第60楼]
------------------
领悟中。。。。。
ltp1234
[第77楼]   [ 回复时间:2012-03-19 23:13 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-04-06 22:45
都是高手
ltp1234
[第78楼]   [ 回复时间:2012-03-19 23:13 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-04-06 22:45
都是高手
ltp1234
[第79楼]   [ 回复时间:2012-03-19 23:13 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-04-06 22:45
都是高手
tiandaochouqin
[第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,理论上是这样的,只是我的猜 想,以上三个问题很是不解。尤其是第一个。请哪位高手给我解答一下,谢谢了。
powlin1991
[第81楼]   [ 回复时间:2012-03-30 13:12 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:5
注册日期:2012-03-22 15:34
回复:[第80楼]
------------------
第一个问题,复制的时候不是复制我们所见到的语句,这里不是复制jmp 0018,而是复制它的机器码过去,机器码在这里的意思是向上跳10位。

第二个问题我也不是很清楚,但是我自己理解应该是计算机默认的。

第三个问题你的猜想是对的,在执行jmp之前,ip已经指向了下一句,所以000A跳到0000就执行第一句话了。
xueyugaoyuan
[第82楼]   [ 回复时间:2012-08-20 10:38 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2012-08-14 17:57
好文章 仔细看了
online6883
[第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 为什么?
qiyao
[第84楼]   [ 回复时间:2012-09-05 17:13 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2012-08-25 20:51
回复:[第83楼]
------------------
为什么不是跳10位?F6补码是-10,就是向上跳10位正好是mov ax,4c00h啊。
你自己不想想清楚就说别人胡说八道,这不太好吧。
whaition
[第85楼]   [ 回复时间:2012-09-26 14:56 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2012-09-26 11:24
我觉得这个是不是给我一个启示,如何控制jmp指令,实现跳出循环?
lishenycy
[第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不是应该是四个字节么?
dingningyu
[第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
dingningyu
[第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
caoqun523
[第89楼]   [ 回复时间:2012-11-07 23:57 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2012-01-01 20:45
刚开始,看也是有点混,但是后来用DEBUG调试了一下,就什么都明白了,看来还得加点劲
acmonster
[第90楼]   [ 回复时间:2014-07-11 18:08 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2014-07-11 18:04
分析的很好,我上初中的时候你们发了这个帖子,现在我大二了,哈哈。
dgkepu
[第91楼]   [ 回复时间:2014-08-06 10:25 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2012-08-27 13:18
分析的很好
uzesi
[第92楼]   [ 回复时间:2017-11-28 04:37 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2017-01-24 04:03
顶,有点明白了,不太懂为什么mov 内存单元,另一个内存单元,
 会把另一个内存单元的代码复制到内存单元中,不是地址吗
需要登录后才能回帖 -->> 请单击此处登录
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved