转移指令的原理
转移指令:可以修改IP或者同时修改CS和IP的指令(jmp、loop、call)
总的来说,转移指令就是可以控制CPU执行内存中某处代码的指令。
8086的转移行为有一下几类:
- 只修改ip时,称为段内转移,比如:jmp ax
- 同时修改cs和ip,称为段间转移,比如:jmp 1000:0
由于转移指令对IP的修改范围不同,段内转移,又分为:短转移和近转移
- 短转移IP的修改范围为:-128~127
- 近转移的IP修改范围为:-32768~32767
loop——》无条件转移指令
jmp——》条件转移指令
操作符offset
伪指令offset在汇编语言中的由编译器处理的符号,它的功能是取得标号的偏移地址。
assume cs:code
code segment
start: mov ax,offset start ;相当于mov ax,0
;start所标记的是代码段的第一条指令,偏移地址为0
s: mov ax,offset s ;相当于mov ax,3
;s所标记的指令是代码段中的第二条指令,第一条指令的长度为3byte,则s的偏移地址为3
code ends
end start
问题:有如下程序段,填写两条指令,使改程序在运行中将s处的第一条指令复制到s0处:
代码如下:
;问题:有如下程序段,填写两条指令,使改程序在运行中将s处的第一条指令复制到s0处:
assume cs:code
code segment
s: mov ax,bx ;mov ax,bx机器码占两个字节
mov si,offset s
mov di,offset s0
mov dx,cs:[si] ;数据从哪里来
mov cs:[di],dx ;数据到哪里去
s0: nop ;cpu遇到nop指令什么都不做,nop指令占一个字节
nop
code ends
end s
JMP指令
8086CPU执行过程
①CPU从cs和ip所组合出来的地址读取数据,将指令放到指令缓冲器中
②IP=IP+所读指令的字节数
③执行指令缓冲器中的内容,跳转到第一步
jmp s
mov bx,1000H
s: mov ax,1000H ;由观察可得此时**JMP指令的机器码是EB04**
再加一条指令:
jmp s
mov bx,1000H
mov bx,1000H
s: mov ax,1000H ;由观察可得此时**JMP指令的机器码是EB07**
jmp跳转指令编译后的机器码和指令的长度有关
CPU在执行jmp指令的时候,并不需要跳转的目的地址就可以实现对IP寄存器的修改,只要做一个加法就好了
编译器如何计算指令长度?
标号地址 - JMP指令后第一个字节的地址
JMP指令可能存在的一个问题:
s: mov ax,1000H
jmp s ;jmp在下面
由标号地址-JMP指令后第一个字节的地址计算得到:(8-D=FB)——》(8-13=-5)
计数器中是没有减法的——》加上一个负数
涉及到补码:
将一个正数变成二进制之后按位取反(0变1,1变0),再加1
eg:5的二进制:0000 0101
取反:1111 1010 +1 =1111 1011(FB)
jmp指令的跳转范围:(向前跳 or 向后跳)
;跳转范围也叫做位移范围 八位位移(-128~127)
十六位位移(-32768~32767)
可以指定是八位位移还是十六位位移:
jmp short s(八位位移)
jmp near ptr s(十六位位移)