| 
 | 
 
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册  
 
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指令后面的地址 |   
 
 
 
 |