转移指令原理

可以修改 IP 或同时修改 CS 和 IP 的指令统称为转移指令。即转移指令就是可以控制 CPU 执行内存中某处的代码的指令。
只修改 IP 时,称为段内转移eg:jmp ax 。
同时修改 CS 和 IP 时,称为段间转移eg:jmp 1000:0。

由于转移指令对 IP 的修改范围不同,段内转移又分为:短转移近转移
♦ 短转移 IP 的修改范围为 -128~127
♦ 近转移 IP 的修改范围为 -32768~32767

8086CPU 的转移指令分类
无条件转移(jmp)
条件转移
循环指令(loop)
过程
中断






操作符 offset
汇编语言中由编译器处理的符号,功能是取得标号的偏移地址
assume cs:codesg
codesg segment
start:    mov ax , offset start              ; 相当于mov ax , 0
s:          mov ax , offset s                    ; 相当于mov ax , 3 ; 汇编指令机器码的第一个字节会告诉CPU这条指令由多少个字节,mov ax , offset start 这条指令占3个字节,所以cs段开始到s偏移3
codesg ends
end start
nop 机器码占一个字节,空指令,只是拿来占位置

; 利用offset复制指令到指定位置; 复制 s 和 s0 处的指令
assume cs:codesg
codesg segment
s:      mov ax , bx               ; 这条指令机器码占两个字节
         mov si , offset s       ; mov si , 0, ; s在cs段开始,偏移0
         mov di , offset s0    ; mov di , 000E,s0的偏移是14
         mov ax , cs:[si]
         mov cs:[di] , ax
s0:    nop                           ; 机器码占一个字节
         nop
codesg ends
end s



nop 代表的机器码90,一个字节 






jmp 指令
无条件转移指令,可以只修改 IP ,也可以同时修改 CS  和 IP 。
jmp 指令需要给出两种信息:
◆ 转移的目的地址
◆ 转移的距离(段间转移、段内短转移、段内近转移)





依据位移进行转移的 jmp 指令
jmp short 标号 (转到标号处执行指令,实现的是段内短转移)
assume cs:codesg
codesg segment
start:      mov ax , 0
               jmp short s
               add ax , 1
s:            inc ax
codesg ends
end start
执行到 jmp , CS:IP 被设置指向 s: 处,ax 就只被加了一次

jmp 指令中不包括转移的目的地址

  //jmp执行后跳过了add ax , 1 ; jmp 指令并不包含转移的目的地址,他是根据转移的位移来计算最终要跳转到的位置,这个位移是根据汇编指令中的“标号”计算出来的。上图中 jmp 指令长是2字节(指令机器码和转移位移),标号处的位移已经计算出来是03,当前 CS:IP = 076A:0003 , 执行 jmp 指令偏移+2,跳转+3;执行完jmp后 CS:IP = 076A:0008,指向指令 inc ax ;

指令“jmp short 标号”功能为:(IP)=(IP)+8位位移。(段内短转移)
◆ 8 位位移=“标号”处的地址 - jmp 指令后的第一个字节的地址;
◆ short 指明此处的位移为 8 位位移,进行段内短转移;
◆ 8 位位移的范围为 -128~127 ,用补码表示;
◆ 8 位位移由编译程序在编译时计算出。
指令“jmp near ptr 标号”功能为:(IP)=(IP)+16位位移。(段内近转移)
◆ 16 位位移=“标号”处的地址 - jmp 指令后的第一个字节的地址;
◆ near ptr 指明此处的位移为 16 位位移;进行段内近转移;
◆ 16 位位移的范围为 -327688~32767 ,用补码表示;
◆ 16 位位移由编译程序在编译时计算出。






转移的目的地址在指令中的 jmp 指令
指令“jmp far ptr 标号”实现的是段间转移,又叫远转移。功能:(CS)=标号所在段的段地址;(IP)=标号在段中的偏移地址。far ptr 指明了指令用标号的段地址和偏移地址修改 CS 和 IP





转移地址在寄存器中的 jmp 指令
指令格式:jmp 16位寄存器
功能:(IP)=(16位寄存器)
jmp 段地址:偏移地址” 或者把先把目的IP放到寄存器,然后直接 “jmp 16位寄存器”





转移地址在内存中的 jmp 指令
jmp word ptr 内存单元地址段内转移
功能:内存单元地址处开始存放着一个字,是转移的目的偏移地址。内存单元地址可用寻址方式的任一格式给出。
eg:mov ax , 0123H
        mov ds:[0] , ax
        jmp word ptr ds:[0]        ; (IP)=0123H
jmp dword ptr 内存单元地址 段间转移
功能:内存单元地址存放着两个字,高地址处的字是转移的目的段地址,低地址处是转移的目的偏移地址。
(CS)=(内存单元地址+2) ;(IP)=(内存单元地址)
内存单元地址可用寻址方式的任一格式给出。
eg:mov ax , 0123H
        mov ds:[0] , ax
        mov word ptr ds:[2] , 0
        jmp  dword ptr ds:[0]      ; 执行后(CS)=0 , (IP)=0123H






jcxz 指令
  有条件转移指令,所有的有条件转移指令都是短转移,对应的机器码中包含转移的位移,而不是目的地址。对 IP 的修改范围都为:-128~127。
指令格式:jcxz  标号如果(cx)=0,转移到标号处执行;(cx)≠ 0 时,指令什么也不做,向下接着执行
操作:当(cx)=0 时,(IP)=(IP)+8 位位移==》8 位位移 =“标号”处的地址-jcxz指令后的第一个字节的地址;





loop 指令
 loop指令为循环指令,所有的有条件转移指令都是短转移,对应的机器码中包含转移的位移,而不是目的地址。对 IP 的修改范围都为:-128~127。
指令格式:loop  标号  ((cx)= ( cx ) - 1 , 如果(cx)≠ 0 时,转移到标号处执行
操作:1、(cx)=(cx)-1 ;   2、如果 ( cx )≠ 0 , ( IP )=( IP )+8 位位移。



根据位移进行转移的意义:方便了程序段在内存中的浮动装配。


原文地址:https://www.cnblogs.com/meihao1203/p/7546066.html