[TOC]
转移指令在高级语言中相当于`goto`命令。
8086CPU指令的分类:
+ 无条件转移
+ 条件转移
+ 循环指令
+ 过程
+ 中断
# 操作符`offset`
功能:获取标号的偏移地址
~~~
assume cs:code
code segment
start:
s: mov ax, bx ; mov ax, bx的机器码占两个字节
mov si, offset s ; 相当于 mov ax, 0
mov ds, offset s0
mov ax, cs:[si]
mov cs:[di], ax
s0: nop ; nop的机器码占一个字节
nop
code ends
ends start
~~~
# `jmp`指令
jmp为无条件转移,可以修改`IP`,也可以同时修改`CS`和`IP`。
参数:
+ 转移的目的地址
+ 转移的距离(段间距里、段内短转移、段内近转移)
## 依据`位移`进行转移的jmp指令
**段内短转移**
~~~
jmp short 标号
~~~
大小为:`1B`,即`2^8`
对`IP`进行修改的范围:`-128-128`
~~~
assume cs:code
code segment
start:
s: mov ax, 0
jmp short s ; 调到标号为s的地方执行,即跳过add ax,1,IP指向了标号 s 出的 inc ax
add ax, 1
s: inc ax
code ends
ends start
~~~
段内近转移:
16bit
相对于当前的`IP`进行转移位移。
## 转移的目的地址在`指令`中的jmp指令
**段间转移(远转移)**
~~~
jmp far ptr 标号
~~~
功能:用标号的段地址和偏移地址修改`CS`和`IP`的值。
~~~
assume cs:code
code segment
start: mov ax, 0
mov bx, 0
jmp far ptr s
dd 256 dup(0)
s: add ax, 1
inc ax
code ends
end start
~~~
## 转移地址在`寄存器`中的jmp指令
~~~
jmp 16位寄存器
~~~
功能:IP = (16位寄存器)
## 转移地址在`内存`中的jmp指令
**第一种方式:**
~~~
jmp word ptr 内存地址 ;(段内转移)word16位
~~~
功能:从内存单元地址处开始存放着一个字,是转移的目的偏移地址。
内存地址可以使用寻址方式的任意一种方式给出:
~~~
mov ax, 0123H
mov ds:[0], ax
jmp word ptr ds:[0] ; jmp ax, (IP) = 0123H
~~~
**第二种方式:**
~~~
jmp dword ptr 内存地址 ;(段间转移),dword32位
~~~
功能:从内存单元处开始存放2个字,高地址的字是**转移的目的段地址**,低地址处是**转移的目的偏移地址**。
(CS)=(内存地址+2)
(IP)=(内存单元地址)
~~~
mov ax, 0123H
mov ds:[0], ax
mov word ptr ds:[2] , 0 ; 强制将00变成16位
jmp dword ptr ds:[0] ; (cs)=0, (IP)=0123H
~~~
# `jcxz`指令
**语法:**
~~~
jcxz 标号 指令操作
~~~
+ 当 `(cx)=0` 时,`(IP)=(IP)+8位位移`
+ 8位位移 = “标号”处的地址 - jcxz指令的最后一个字节的地址
+ 8位位移的范围: -128-127,由程序编译时计算出
相当于
~~~
if(cx == 0)
jmp short 标号
~~~
# `loop`指令
所有的循环指令都是`短转移`,对`IP`的修改范围为`-128~127`。
**格式**
~~~
loop 标号
~~~
(cx) = (cx) - 1,如果(cx)不等于0,则转移到标号出执行。
# 根据位移进行转移的意义
# 编译器对转移越界的检测
