汇编语言中,jmp short指令是8位转移指令,可以修改ip寄存器的范围为-128~127 (8位补码的表示范围,因为偏移地址计算使用的是补码)
短转移指令的机器码格式为EB??,其中??表示8位偏移地址,接下来研究??的计算方法。
一、公式介绍
要计算jmp short的偏移地址,我们要记住公式:
偏移地址=标记处的偏移地址-CPU读完该jmp指令后的ip寄存器值
二、方法步骤
1.后跳转
我们引入MASM中的代码片段
DATAS SEGMENT
DATAS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
jmp short s
mov ax,1000H
mov ax,1000H
mov ax,1000H
s:mov bx,ax
MOV AH,4CH
INT 21H
CODES ENDS
END START
s位于jmp指令的后面。
编译后进行debug,使用u指令查看汇编指令,如下图:
可以看到标记s处的偏移地址为0010H,CPU读取完jmp指令后ip指向了0007H,找到了这两个关键数据后套用公式:偏移地址=标记地址-ip地址,即0010H-0007H。
在计算机中,减法运算是转换成加法进行,即-x转化成+(x)补,需要将减号后面的数字转换成补码:
0010H=0000 0000 0001 0000B
0007H=0000 0000 0000 0111B
(0007H)补=1111 1111 1111 1001B
进行加法运算:0000 0000 0001 0000B + 1111 1111 1111 1001B=1 0000 0000 0000 1001B
在这里要注意:
进行的是8位的加减法,超过8位的数据要进行舍弃
得到结果0000 1001B,即09H的补码
所以得出结果:??=09,原来jmp指令的机器码为EB09。
大家可以在jmp指令前加上 dd 100 dup (1),讲jmp指令的偏移地址增大,得到的结果也是符合这个计算公式的。后跳转这种情况得以认证。
2.前跳转
前跳转指令就是标记位置在jmp指令的前面,引入代码:
DATAS SEGMENT
DATAS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS
START:
MOV AX,DATAS
s:MOV DS,AX
dd 10 dup (3)
jmp short s
mov ax,1000H
mov ax,1000H
mov ax,1000H
mov bx,ax
MOV AH,4CH
INT 21H
CODES ENDS
END START
将s定位在mov ds,ax位置,中间定义10个双字变量,jmp指令位于后面。
注意:dup不要太大了,超过了jmp short 的范围会报错。
指令分布如下图:
我们可以看到,s标记的偏移地址是0003H,CPU执行完jmp指令后的偏移地址是002FH,根据以上计算公式:
0003H=0000 0000 0000 0011B;
002FH=0000 0000 0010 1111B;(002FH)补=1111 1111 1101 0000B
0003H-002FH=0000 0000 0000 0011B +1111 1111 1101 0001B=1111 1111 1101 0100B
舍去8位以后的数据,得到1101 0100B,即(D4H)的补码,JMP指令的机器码为EBD4,上述结论得以验证。
综上,偏移地址的计算方法为:
找到CPU读取jmp指令后的IP寄存器值,即jmp的下一条指令的偏移地址;
找到标记位,即jmp 目标的偏移地址;
进行标记位地址-IP寄存器值的补码运算,得到的补码结果就是短跳转指令的偏移地址。
来源:oschina
链接:https://my.oschina.net/u/4407552/blog/4467951