可以修改 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 位位移。
根据位移进行转移的意义:方便了程序段在内存中的浮动装配。