曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 6116|回复: 0
打印 上一主题 下一主题

[8086] 转移指令

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34387
跳转到指定楼层
楼主
发表于 2009-4-1 01:06:15 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1、8086的转移行为
可以修改IP,或同时修改CS和IP的指令统称为转移指令。
      只修改 IP 时,称为段内转移,如 jmp ax
      同时修改 CS 和 IP 时,成为段间转移,如 jmp 1000:0
根据转移指令对 IP 的修改范围不同,段内转移又分为:短转移近转移
      短转移 IP 的修改范围为 -128 ~ 127
      近转移 IP 的修改范围为 -23768 ~ 32767
8086 的转移指令分为以下几类
      无条件转移指令
      条件转移指令
      循环指令
      过程
      中断
2、操作符 offset
offset 在汇编语言中是由编译器处理的符号,功能是取得标号的偏移地址。
3、转移指令 JMP
     <1>根据 位移 进行转移的 JMP 指令
     有两种:jmp short 标号(转到标号处执行指令,段内短转移,范围为 -128 ~ 127)
                   jmp near 标号 (段内近转移,范围为 -32768 ~ 32767)
    指令本质:(下例说明)
     偏移地址                       机器码                                             汇编指令
     0000                             40                                                   s: inc ax
     0001                             EB03                                                   jmp s0
     0003                             BB0300                                               mov bx,3
     0006                             43                                                  s0: inc bx
     0007                             EBF7                                                    jmp s
     0009                             90                                                        nop

问题:为什么 jmp s0 的机器码中 EB 后面是 03?
          为什么 jmp s 的机器码中 EB 后面是 F7?
解析指令执行过程:
(1) 当CS:IP为 CS:0001 时,CS:IP 指向 EB03 ,即指令 jmp s0
(2) 读取指令码 EB03 进入指令缓冲器
(3) 此时,CS:IP 指向 mov bx,3,即现在 IP = 0003
(4) CPU 执行指令缓冲器中的指令 EB03
(5) 指令 EB03 执行后,(IP) = 0003H + 3 = 0006 ,CS:IP 指向 inc bx
(6) 当把 jmp s 装入指令缓冲器时,IP 为0009,在 nop 指令处。标号 s 的 IP:0000,故这两点指令的“距离”(位移量):0 - 9 = -9( 补码即为 F7 ,也就相当于从 0009 处往后条 9 个字节 )。
 ----------------------------------------------------------------------------------------------------------
因此,在 “jmo short 标号” 指令所对应的机器码中,并不包含转移的目的地址,而包含的是转移的位移。这个位移,是编译器根据汇编指令中的 “标号” 计算出来的。

实际上,“jmp short 标号”的功能为:(ip) = (ip) + 8 位位移
             (1) 8位位移 = “标号”处的地址 - jmp 指令后的第一个字节的地址;
                  (如上面的,就是 11 - 8 = 3,位移为 3 )
             (2) short 指名此处的位移是 8 位位移。
             (3) 8 位的位移的范围为 -128 ~127,用补码表示。
           (4)8位位移由编译程序在编译时算出。
另外,“jmp near 标号”实现段内近转移,功能是(ip) = (ip) + 16。

<2> 转移的目的地址在指令中的 jmp 指令
       jmp far ptr 标号----实现的是段间转移,又称为远转移。功能如下:
   CS = 标号所在段的段地址; IP = 标号在段中的偏移地址。 

<3>  转移地址在寄存器中的 jmp 指令
       指令格式: jmp 16位寄存器
       功能: (ip) = (16位寄存器)

<4>  转移地址在内存中的 jmp 指令
  两种形式:
 (1) jmp word ptr 内存单元地址( 段内转移 )
      功能:从内存单元地址开始存放着一个字,是转移的目的偏移地址。内存单元地址可用寻址方式的任一格式给出。
(2) jmp dword ptr 内存单元地址(段间转移)
     功能:从内存单元地址开始存放着两个字,高地址处的字是转移的目的段地址,低地址处是转移的目的偏移地址。
<5> 一个小实验
代码如下:
[Plain Text] 纯文本查看 复制代码
assume cs:codedata segment
     dd 00000000H
data ends
code segment
    
    start:
            mov ax,data
            mov ds,ax
            mov bx,0   
            mov [bx],bx
            mov [bx + 2],code
      
            jmp dword ptr ds:[bx]
code ends
end  start

表中程序,在用masm和Link是可以编译通过并正确执行的,但是用emu8086却不行---出错在 mov [bx + 2],code
上。但是最为稳妥的做法是 mov [bx + 2], cs。可能两个编译器对 code 这样的一个标号解释不太一样。在emu8086仿真软件上,需要这么写 mov [bx + 2], word ptr [mw_shl_code=text,true] 或者先 mov ax,code,然后再mov [bx +2], ax。

2、jcxz 指令
     jcxz 指令为有条件转移指令,所有的有条件转移指令都是短转移,在对应的机器码中包含转移的位移,而不是目的地址。对 IP 的修改范围为: -128 ~ 127。
    功能:cx  = 0 则 转移到标号处。cxz(cx is zero)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2024-5-20 14:58 , Processed in 0.063630 second(s), 23 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表