马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
前言
可以修改IP,或同时修改CS和IP的指令统称为转移指令。转移指令能够控制CPU执行某处的代码的指令。
8086CPU的转移分如下几类:
1、只能修改IP的称为段内转移, 如:jmp ax
2、同时修改CS和IP称为段间转移,如:jmp dword ptr 内存地址 注意:jmp 1000:0这个指令只能在debug中使用
由于段内转移对修改的范围不同,又有段转移和近转移。
1、段转移:修改范围是 -128~127
2、近转移:修改范围是 -32768~32767
8086CPU的转移指令又分一下几类:
1、无条件转移,如:jmp
2、条件转移,如:jcxz
3、循环指令,如;loop
4、过程
5、中断
9.1节 操作符offset
操作符offset在汇编语言中是由编译器处理的符号,它的功能取得标号的偏移地址。
如:assume cs: code
code segment
start : mov ax, offset start ;相当于mov ax, 0
s : mov ax, offset s ;相当于mov ax, 3
code ends
end start
问题:在如下程序添加两条指令,使该程序在运行中将s处的一条指令复制到s0处。
代码如下:assume cs: code
code segment
start : mov ax, bx ;此行代码占2个字节的机器码
mov si, offset start
mov di, offset s
mov ax, cs:[si]
mov cs:[di], ax
s : nop
nop
code ends
end start
其实就是将s处的机器码放在ax中,然后再将ax中的内容放在s0中
9.3节 根据位移进行转移的jmp指令
jmp short 标号(转到标号处进行执行),这种格式进行段内短转移,范围是-128~127
如:assume cs: code
code segment
start : mov ax, 0
jmp short s
add ax, 1
s : inc ax
code ends
end start
执行后ax = 1,因为它没有执行add ax, 1直接jmp到inc ax中执行。
重点来了:CPU执行jmp指令时并不需要转移的目的地址,只需要8位的位移 = 标号处的地址 - jmp指令后的第一个字节的地址,这个会在jmp指令的机器码中的,用补码表示
实际上:jmp short 标号的功能为:(IP) = (IP) + 8位位移
(1)8位的位移 = 标号处的地址 - jmp指令后的第一个字节的地址;
(2)short指明此处的位移为8位位移
(3)8位位移的范围为-128~127,用补码表示
(4)8位位移由编译程序在编译时算出
“jmp near ptr 标号”的功能为:(IP) = (IP) + 16位位移
(1)16位的位移 = 标号处的地址 - jmp指令后的第一个字节的地址;
(2)near ptr指明此处的位移为16位位移
(3)16位位移的范围为-32768~32767,用补码表示
(4)16位位移由编译程序在编译时算出
“jmp far ptr 标号”为段间转移,又称远转移。功能:(CS) = 标号所在的段地址, (IP) = 标号所在段中的偏移地址。
far ptr指明了用标号的段地址和偏移地址修改了CS和IP
程序:assume cs: code
code segment
start : mov ax, 0
mov bx, 0
jmp far ptr s
db 256 dup (0)
s : add ax, 1
inc ax
code ends
end start
这个程序的机器码是:
可以看到jmp far ptrs所在的机器码为:EA 0B 01 BD 0B 可知转移的段地址为:DBBDH,转移的偏移地址为010BH
转移地址在寄存器的jmp指令:jmp 16位reg,功能:(IP) = (16位reg)
9.6节 转移地址在内存在的jmp指令
(1)jmp word ptr 内存单元地址(段内转移)
如: mov ax, 0123H
mov ds:[0], ax
jmp word ptr ds:[0]
执行后(IP) = 0123H
(2)jmp dword ptr 内存单元地址(段间转移)
功能:从内存单元地址开始处放着两个字,高地址的字是转移的目的的段地址,低地址处的是转移的目的的偏移地址,
(CS) = (内存单元地址 + 2)
(IP) = (内存单元地址)
mov ax , 0123H
mov ds, ax
mov bx, 0
mov word ptr ds:2[bx], 0
jmp dword ptr ds:[bx]
执行后,(CS) = 0, (IP) = 0123H,CS:IP指向0000:0123
9.7 节 jcxz 指令
指令格式:jcxz 标号 (如果cx为0,转移到标号处执行)
操作:当(cx) = 0时,(IP) = (IP) + 8位位移
(1)8位的位移 = 标号处的地址 - jcxz指令后的第一个字节的地址;
(2)8位位移的范围为-128~127,用补码表示
(3)8位位移由编译程序在编译时算出
用C语言描述为 if (cx == 0) { jmp short 标号}
9.8 节 loop 指令
指令格式:loop 标号((CX) = (CX) - 1, 如果CX不为0,则转移到标号处执行)
操作:
(1)(cx) = (cx) - 1;
(2)如果cx不为0,则转移到标号处执行
C语言描述为;
(cx) --;
if (cx != 0) {jmp short 标号}
总结
(1)操作符offset功能是取得标号处的偏移地址,由编译器操作
(2)jmp short 标号、jmp near ptr 标号称为段内转移,范围分别是-128~127和-32768~32767
(3)jmp far ptr 标号表示段间转移,CS为标号所在的段地址,IP为标号所在的偏移地址
(4)jmp word ptr 内存单元只能修改IP,而jmp dword ptr 内存单元能修改CS和IP, CS在[内存单元 + 2] ,IP在[内存单元]中,高地址存放在CS中,低地址在IP中
(5)还有jcxz指令,cx为0时就转移到jcxz 标号处,还有熟悉的loop指令
(6)还有就是重点的是:转移指令不存放转移的目的地址,只存放标号所在的地址 - jmp指令后面的地址 |