本博文系列参考自<<汇编语言>>第三版,作者:王爽
可以修改IP寄存器的值,或者同时修改CS与IP的值的指令称为转移指令。转移指令的功能就是使得CPU执行内存中某段特定的指令或程序。
8086CPU的转移行为分为如下几类;
1.只改变IP值,称为段内转移。比如 jmp ax;段内转移又分为短转移和近转移。短转移IP的修改范围为-128~127,近转移IP的修改范围为-32768~32767.
2.同时改变CS:IP的值称为段间转移。比如 jmp 1000:0
8086CPU的转移指令分为如下几种:
无条件转移指令:jmp
条件转移指令
循环指令
过程
中断
本次博文主要介绍jmp指令
9.1 操作符offset
offset为伪指令,该指令由编译器解释。offset的作用是取得标号的偏移地址.比如:
<pre name="code" class="plain">assume cs:codesg
codesg segment
start: mov ax,offset start 含义:相当于mov ax,0
s: mov ax,offset s 含义:相当于mov ax,3
codesg ends
end start
9.2 jmp指令
jmp为无条件转移指令,可以只修改IP寄存器的值,也可以同时修改CS与IP的值。
jmp指令要给出两种信息:
(1)转移的目的地址
(2)转移的距离(段间转移,段内短转移,段内近转移)
9.3依据位移进行转移的jmp指令
jmp short 标号(转到标号处执行指令)
这里short代表的是段内短转移,向前可转移128个字节,向后可转移127个字节。
标号代表目的地址。
指令结束后,cs:ip指向标号处的指令
这里需要说明一点:
有如下代码段:
代码段1:
assume cs:codesg
codesg segment
start:mov ax,0
jmp short s
add ax,1
s:inc ax
codesg ends
end start
代码段2:
assume cs:codesg
codesg segment
start:mov ax,0
mov bx,0
jmp short s
add ax,1
s:inc ax
codesg ends
end start
代码段1和代码段2翻译成机器码:两个代码段的中jmp short s指令的机器指令分别为:
机器码 汇编指令
代码段1: EB03 JMP 0008
代码段2: EB03 JMP 000B
可以看出汇编指令的0008和000B分别为两个代码段中s标号的偏移地址,然而两个代码段中jmp short s对应的机器码都是一样的,均为EB03.说明机器码中并不包含跳转的目的地址。
其实错了其中 EB03中的03即为将要跳转的标号处的地址为当前IP值加3.
所以 jmp short 标号 的跳转是根据当前IP值与标号处指令地址的偏移值进行跳转的
9.4转移的目的地址在指令中的jmp指令
jmp far ptr 标号 实现段间转移
功能为:CS=标号处的段地址 IP=标号处的偏移地址
far ptr 标号指明了使用标号处的段地址和偏移地址修改CS和IP
下面的代码:
assume cs:codesg
codesg segment
start: mov ax,0
mov bx,0
jmp far ptr s
db 256 dup (0)
s:add ax,1
inc ax
codesg ends
end start
翻译成机器码:
jmp far ptr s的汇编为jmp 14FF:010B 机器码为EA0B01FF14 可以看出汇编指令和机器码中均包含了段地址14FF和偏移地址010B
9.5转移地址在寄存器中的jmp指令
比如jmp ax 这很容易理解,即将IP的值改为AX寄存器中存储的值进而实现跳转
9.6转移地址在内存中的jmp指令
jmp word ptr 内存地址(段内转移)
比如:
mov ax,0123h
mov ds:[0],ax
jmp word ptr ds:[0]
其含义为 IP=0123H
再比如:
mov ax,0123h
mov [bx],ax 含义:((ds)*16+(bx))=(ax)
jmp word ptr [bx]
此时IP=0123h
jmp dword ptr 内存地址(段间转移) 高地址的字存放段地址,低地址的字存放偏移地址
(CS)=(内存地址+2)
(IP)=(内存地址)
比如:
mov ax,0123h
mov ds:[0],ax
mov word ptr ds:[2],0
jmp dword ptr ds:[0]
此时
(CS)=0000H,(IP)=0123H
又比如:
mov ax,0123h
mov [bx],ax
mov word ptr [bx+2],0
jmp dword ptr [bx]
此时(CS)=0000H,(IP)=0123H
9.7 jcxz指令
jcxz指令为有条件转移指令,所有有条件转移指令都为段内段转移指令
指令格式:
jcxz 标号(如果(cx)=0,则转移到标号处执行)
可以这样理解:
if((cx)==0) jmp short s
9.8 loop指令
loop为循环指令,所有的循环指令均为段内短转移指令
指令格式 loop s(如果(cx)!=0,转移到标号处执行)
可以这样理解:
(cx)--
if((cx)!=0) jmp short s
9.9根据位移进行转移的意义以及编译器对转移位移超界的检测
jmp short s
jmp near ptr s
jcxz s
loop s
均为根据当前指令相对于标号处的位移进行更改IP的转移指令,这些指令的机器码中并不包括跳转目的地址,仅仅包含位移量。
当时针对短转移跳转指令,如果跳转位置超过正的127或者负的128都会出现移位超界,此时编译器会报错,务必注意这一点。