. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
刷新 | 提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->转移指令的原理
  管理员: assembly   [回复本贴] [收藏本贴] [管理本贴] [关闭窗口]
主题 : :  分析一个奇怪的程序遇到问题?  [待解决] 回复[ 34次 ]   点击[ 2461次 ]  
lovecpu
[帖 主]   [ 发表时间:2007-06-26 20:49 ]   [引用]   [回复]   [ top ] 
荣誉值:5
信誉值:3
注册日期:2007-06-26 20:40
分析下面的程序,在运行前思考:这个程序可以正确返回吗?  
  运行后再思考:为什么是这种结果?  
   
   
  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
zysong
[第1楼]   [ 回复时间:2007-07-13 11:57 ]   [引用]   [回复]   [ top ] 
荣誉值:19
信誉值:0
注册日期:2007-07-05 17:25
可以正确返回。
这和jmp的执行原理有关系,请看第九章的分析。
上机做实验看看就知道了。
Wednesday
[第2楼]   [ 回复时间:2007-08-19 12:33 ]   [引用]   [回复]   [ top ] 
荣誉值:43
信誉值:3
注册日期:2007-07-05 19:53
最好反复思考得出自己的结论之后再上机实验。

很有趣,也会很有收获。
up4tree
[第3楼]   [ 回复时间:2007-09-16 09:26 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2007-08-29 11:41
关键在 jmp   short   s1   这一步
这一步在 s2处执行的时候是ip向上偏移了“3行”

mov   di,offset   s   
  mov   si,offset   s2   
  mov   ax,cs:[si]   
  mov   cs:[di],ax   
复制到s:处也还是向上偏移了“3行”
所以,由s0: jmp   short   s   ,再执行s:的时候,就会执行
mov   ax,4c00h   
  int   21h   

从而可以正常的返回。
lyman
[第4楼]   [ 回复时间:2008-02-25 18:09 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2007-12-11 10:23
其实这个实验有两个最关键的关键点:
1。“jmp short 标号”的原理。
2。程序是编译后才运行的。
理解清楚了这两点就什么都好办了。
wjw3072003
[第5楼]   [ 回复时间:2008-04-10 15:02 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2008-03-14 16:22
嗯,有收获啊
duckgaga
[第6楼]   [ 回复时间:2008-04-14 20:58 ]   [引用]   [回复]   [ top ] 
荣誉值:44
信誉值:0
注册日期:2008-04-11 13:33
嗯,明白其原理就能知道它可以正确返回了。
jmp   short   s 在编译时,是根据标号与JMP下一条指令的偏移量来确定的,因此偏移量不变其功能不变
thisguy
[第7楼]   [ 回复时间:2008-05-28 23:40 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:2
注册日期:2008-04-02 16:04
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字节,于是便跳到了代码中的第一条指令,继续执行后便实现了程序的正常返回。
applemo
[第8楼]   [ 回复时间:2008-08-01 18:36 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2008-07-17 09:29
为什么我上机测试之下,正确返回不是应该显示 "Program terminated normally",但为什么这题不会(即已经执行完S处的EBF6指令之后,跳到了代码中的第一条指令)!
vizwind
[第9楼]   [ 回复时间:2008-09-27 03:41 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2008-09-15 15:58
重要的一点是jmp short的跳转地址偏移是在编译时计算出来的,所以jmp short指令被复制后,跳转的地址偏移保持不变,并不会重新计算。
mengxinjinglong
[第10楼]   [ 回复时间:2008-12-02 13:55 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2008-09-15 21:00
噢噢 以前一直没有好好注意  所以也不清楚 才到这里看看  受教了
呵呵 好像这个帖挺长的一个时间差啊
asher
[第11楼]   [ 回复时间:2008-12-19 15:02 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2008-12-09 16:33
assume cs:codesg

data segment
db 'welcome to masm!'
db 02h,24h,71h
data ends

codesg segment
start: 
        
        mov ax,data
        mov ds,ax
        mov bx,0
        mov cx,3
        mov si,0
        mov di,0
        mov ax,stack
        mov ss,ax
        mov sp,04h
        mov bp,0

        s1:
        mov dx,cx        
        mov cx,16

        s:        
        
        mov ax,0b872h 
        mov es,ax
        mov al,ds:[si]
        mov ah,ds:10h[bp]
        mov es:[bx+di],ax
        
        add di,2
        add si,1
        loop s

        mov cx,dx
        mov ax,0
        mov si,0
        mov di,0
        add bp,1
        add bx,0a0h
        loop s1

        mov ax,4c00h
        int 21h
codesg ends

end start
windflower
[第12楼]   [ 回复时间:2009-02-02 13:28 ]   [引用]   [回复]   [ top ] 
荣誉值:2
信誉值:0
注册日期:2009-01-28 11:57
请问11楼,你定义了stack段吗? 你的第15行 mov ax,stack  mov ss,ax可以吗?
lxk_ideal
[第13楼]   [ 回复时间:2009-05-06 12:49 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-04-22 18:44
up4tree(3楼) 和thisguy (7楼)分析的正确。
0617525
[第14楼]   [ 回复时间:2009-05-25 12:27 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-05-22 19:48
3q  7楼解释的很明白~
nick
[第15楼]   [ 回复时间:2009-08-26 19:51 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-08-17 01:35
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   

看这里  就OK了
zhllhz
[第16楼]   [ 回复时间:2009-12-19 21:23 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:4
注册日期:2009-12-18 19:17

帖子有段时间了

老师那会儿建议是:大家象计算机一样思考

大家试试吧

持之以恒应该会有很大收获
呵呵
thedaydreamwang
[第17楼]   [ 回复时间:2010-01-09 03:57 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-10-07 14:18
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

C:\>debug32 c:\masm\qi.exe
Debug32 - Version 1.0 - Copyright (C) Larson Computing 1994

CPU = 686, Virtual 8086 Mode, Id/Step = 067A, A20 enabled
-r
AX=0000  BX=0000  CX=0023  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000
DS=2186  ES=2186  SS=2196  CS=2196  IP=0005  NV UP DI PL NZ NA PO NC
2196:0005 B80000           MOV     AX,0000h
-u
2196:0008 90               NOP
2196:0009 90               NOP
2196:000A BF0800           MOV     DI,0008h
2196:000D BE2000           MOV     SI,0020h
2196:0010 2E8B04           MOV     AX,CS:[SI]
2196:0013 2E8905           MOV     CS:[DI],AX
2196:0016 EBF0             JMP     Short 0008

2196:0018 B80000           MOV     AX,0000h
2196:001B CD21             INT     21h
2196:001D B80000           MOV     AX,0000h
2196:0020 EBF6             JMP     Short 0018

2196:0022 90               NOP
thedaydreamwang
[第18楼]   [ 回复时间:2010-01-09 04:02 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-10-07 14:18
不明白 为什么会没有了 2196:0017 和 2196:21    编译的时候通过了只是结果让我产生了很多疑问,现在还没有用t到执行,想多思考一下在去实验!!!
thedaydreamwang
[第19楼]   [ 回复时间:2010-01-10 01:47 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-10-07 14:18
今天终于把实验做了一遍实验过程如下
C:\>debug32 c:\masm\qiguai.exe
Debug32 - Version 1.0 - Copyright (C) Larson Computing 1994

CPU = 686, Virtual 8086 Mode, Id/Step = 067A, A20 enabled
-r
AX=0000  BX=0000  CX=0023  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000
DS=2186  ES=2186  SS=2196  CS=2196  IP=0005  NV UP DI PL NZ NA PO NC
2196:0005 B80000           MOV     AX,0000h
-u
2196:0008 90               NOP
2196:0009 90               NOP
2196:000A BF0800           MOV     DI,0008h
2196:000D BE2000           MOV     SI,0020h
2196:0010 2E8B04           MOV     AX,CS:[SI]
2196:0013 2E8905           MOV     CS:[DI],AX
2196:0016 EBF0             JMP     Short 0008

2196:0018 B80000           MOV     AX,0000h
2196:001B CD21             INT     21h
2196:001D B80000           MOV     AX,0000h
2196:0020 EBF6             JMP     Short 0018

2196:0022 90               NOP
-r
AX=0000  BX=0000  CX=0023  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000
DS=2186  ES=2186  SS=2196  CS=2196  IP=0005  NV UP DI PL NZ NA PO NC
2196:0005 B80000           MOV     AX,0000h
-t
AX=0000  BX=0000  CX=0023  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000
DS=2186  ES=2186  SS=2196  CS=2196  IP=0008  NV UP DI PL NZ NA PO NC
2196:0008 90               NOP
Trace Interrupt
-t
AX=0000  BX=0000  CX=0023  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000
DS=2186  ES=2186  SS=2196  CS=2196  IP=0009  NV UP DI PL NZ NA PO NC
2196:0009 90               NOP
Trace Interrupt
-t
AX=0000  BX=0000  CX=0023  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000
DS=2186  ES=2186  SS=2196  CS=2196  IP=000A  NV UP DI PL NZ NA PO NC
2196:000A BF0800           MOV     DI,0008h
Trace Interrupt
-t
AX=0000  BX=0000  CX=0023  DX=0000  SP=0000  BP=0000  SI=0000  DI=0008
DS=2186  ES=2186  SS=2196  CS=2196  IP=000D  NV UP DI PL NZ NA PO NC
2196:000D BE2000           MOV     SI,0020h
Trace Interrupt
-t
AX=0000  BX=0000  CX=0023  DX=0000  SP=0000  BP=0000  SI=0020  DI=0008
DS=2186  ES=2186  SS=2196  CS=2196  IP=0010  NV UP DI PL NZ NA PO NC
2196:0010 2E8B04           MOV     AX,CS:[SI]
Trace Interrupt
-t
AX=F6EB  BX=0000  CX=0023  DX=0000  SP=0000  BP=0000  SI=0020  DI=0008
DS=2186  ES=2186  SS=2196  CS=2196  IP=0013  NV UP DI PL NZ NA PO NC
2196:0013 2E8905           MOV     CS:[DI],AX
Trace Interrupt
-u 2196:0
2196:0000 B8004C           MOV     AX,4C00h
2196:0003 CD21             INT     21h
2196:0005 B80000           MOV     AX,0000h
2196:0008 90               NOP
2196:0009 90               NOP
2196:000A BF0800           MOV     DI,0008h
2196:000D BE2000           MOV     SI,0020h
2196:0010 2E8B04           MOV     AX,CS:[SI]
2196:0013 2E8905           MOV     CS:[DI],AX
2196:0016 EBF0             JMP     Short 0008

2196:0018 B80000           MOV     AX,0000h
2196:001B CD21             INT     21h
-r
AX=F6EB  BX=0000  CX=0023  DX=0000  SP=0000  BP=0000  SI=0020  DI=0008
DS=2186  ES=2186  SS=2196  CS=2196  IP=0013  NV UP DI PL NZ NA PO NC
2196:0013 2E8905           MOV     CS:[DI],AX
-t
AX=F6EB  BX=0000  CX=0023  DX=0000  SP=0000  BP=0000  SI=0020  DI=0008
DS=2186  ES=2186  SS=2196  CS=2196  IP=0016  NV UP DI PL NZ NA PO NC
2196:0016 EBF0             JMP     Short 0008
Trace Interrupt
-u 2196:0
2196:0000 B8004C           MOV     AX,4C00h
2196:0003 CD21             INT     21h
2196:0005 B80000           MOV     AX,0000h
2196:0008 EBF6             JMP     Short 0000

2196:000A BF0800           MOV     DI,0008h
2196:000D BE2000           MOV     SI,0020h
2196:0010 2E8B04           MOV     AX,CS:[SI]
2196:0013 2E8905           MOV     CS:[DI],AX
2196:0016 EBF0             JMP     Short 0008

2196:0018 B80000           MOV     AX,0000h
2196:001B CD21             INT     21h
2196:001D B80000           MOV     AX,0000h
-u
2196:0020 EBF6             JMP     Short 0018

2196:0022 90               NOP
2196:0023 0000             ADD     [BX+SI],AL
2196:0025 0000             ADD     [BX+SI],AL
2196:0027 0000             ADD     [BX+SI],AL
2196:0029 0000             ADD     [BX+SI],AL
2196:002B 0000             ADD     [BX+SI],AL
2196:002D 0000             ADD     [BX+SI],AL
2196:002F 0000             ADD     [BX+SI],AL
2196:0031 0000             ADD     [BX+SI],AL
2196:0033 0000             ADD     [BX+SI],AL
2196:0035 0000             ADD     [BX+SI],AL
感觉最重要的地方是对EBF6的理解,其次是编译的问题,因为程序是要先经过编译再到cpu中运行,cup 并不执行编译的过程,我用的是masm5.0编译器
vsbat
[第20楼]   [ 回复时间:2010-03-03 20:46 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2010-02-27 23:38
jmp short s
编译时 转换成 相对位移
ltl_8888
[第21楼]   [ 回复时间:2010-04-06 17:23 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2010-03-29 16:48
7、4楼、优秀,终于看明白了~
chever19
[第22楼]   [ 回复时间:2010-07-18 11:33 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2010-07-12 14:54
大家现在都知道S2:处的机器码是EBF6,是偏移-10的意思。但大家有没注意AX的内容?AX是 F6EB。内存中的存放是这样的 EB F6 。也就是说,指令和数据的读取顺序不一样!对吗??
wshyhm
[第23楼]   [ 回复时间:2010-09-29 11:09 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2010-06-19 23:55
4、7楼太酷了。   我说一下22楼的问题吧:数据的高位字节对应高位内存地址,低位字节对应低位内存地址。这是数据的读取规则。送往AX的是数据!
xxie2010
[第24楼]   [ 回复时间:2011-01-20 13:13 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-01-14 12:26
3楼给我很多启发,顶!
thedaydreamwang
[第25楼]   [ 回复时间:2011-02-26 01:56 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-10-07 14:18
大家真的名白了吗???EBF6不是偏移-10的意思(肯定是没做实验,强烈要求做实验哈!!)
allenxiaomai
[第26楼]   [ 回复时间:2011-05-01 16:31 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-04-13 10:10
回复:[第7楼]
------------------
七楼说的很明白,小弟受教了。不过,有点小疑问:
[此位移量也可由指令's2:jmp short s1'处的偏移地址18h减去指令's2:jmp short s1'后一个字节的偏移地址22h得出]
为什么可以这样算啊??
till
[第27楼]   [ 回复时间:2011-06-12 12:56 ]   [引用]   [回复]   [ top ] 
荣誉值:3
信誉值:0
注册日期:2008-06-04 16:24
回复:[第26楼]
有点小疑问:
[此位移量也可由指令's2:jmp short s1'处的偏移地址18h减去指令's2:jmp short s1'后一个字节的偏移地址22h得出]
为什么可以这样算啊??
------------------
回复:jmp short 标号的功能为:(IP)=(IP)+8位位移。位移由:标号处的地址-jmp指令后的第一个字节的地址”于是就由0018h-0022h=-000ah(-00ah即十进制-10,补码表示为:F6。)
cjlchenjilin
[第28楼]   [ 回复时间:2011-07-01 14:06 ]   [引用]   [回复]   [ top ] 
荣誉值:1
信誉值:0
注册日期:2011-05-30 14:33
bu cuo !(0 v 0)!
ilyou2049
[第29楼]   [ 回复时间:2011-11-12 21:54 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2010-02-02 22:22
大家象计算机一样思考,很有道理
jary163
[第30楼]   [ 回复时间:2011-11-14 21:30 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-08-26 16:03
哈哈,这不是书上的那道题吗,呵呵
floverseas
[第31楼]   [ 回复时间:2013-08-13 16:49 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2013-08-09 19:11
很好,真希望多碰到这种题目
dgkepu
[第32楼]   [ 回复时间:2014-08-06 10:21 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2012-08-27 13:18
7楼解释非常清楚
ijuslinasm
[第33楼]   [ 回复时间:2016-01-20 20:34 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2016-01-08 09:56
我觉得楼上都解释的太复杂了。
要明白实验8,要明白2点。
1、汇编指令是机器码的表现形式。也就是,我们看到的是汇编指令,其实应该透过指令看到它所代表的机器码。
2、CPU执行指令的过程。

然后,对这个实验8,本人分析如下。
 当执行到s0处的指令jmp short s,
                 跳转到  标号s 处的指令,这个时候,根据前面代码的效果,s处的指令应该是 jmp short  s1
                  这个时候,如果理解为,跳转到s1就错了。
                  应该看到,汇编指令只是我们理解的表现形式,机器CPU真正执行的是这条汇编指令表示的
                  机器码。
                  jmp short s1  对应的机器码是 EB  F6。此处指令的偏移地址(IP)=0008H。    EB代表指令jmp,F6代表位移。
                   F6转化为十进制是-10
                  根据跳转原理,(IP)=(IP)+(-10).
                  根据CPU执行指令的过程,读取s:jmp short  s1这条指令到指令缓冲器后,IP指向mov di,offset s
                   ,即此时IP=000AH
                   然后机器CPU执行EB  F6,然后(IP)=000AH+(-10)=0000H。指向mov ax,4c00H
jshm
[第34楼]   [ 回复时间:2016-02-02 10:20 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2016-02-02 09:48
33楼的解释非常经典,尤其是这句“汇编指令只是我们理解的表现形式,机器CPU真正执行的是这条汇编指令表示的机器码。”
需要登录后才能回帖 -->> 请单击此处登录
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved