×
嵌入式 > 技术百科 > 详情

汇编入门学习笔记 (八)—— 转移指令

发布时间:2020-06-20 发布时间:
|
疯狂的暑假学习之  汇编入门学习笔记 (八)——  转移指令

 

参考: 《汇编语言》 王爽 第9章

 

可以修改ip或者同时修改cs和ip的指令统称为转移指令。

8086CPU转移行为分为:

段内转移:只修改ip

段间转移:同时修改cs和ip

 

段内转移按ip修改的范围可分为:

短转移:ip修改范围 -128~127

近转移:ip修改范围 -32768~32767

 

转移指令分为:

无条件转移指令。如 jmp

条件转移指令

循环指令。如 loop

过程。

中断。

 

 

1. offset,nop指令

 

offset 获取标号的偏移地址

nop 占用1一个字节

例子:

  1. assume cs:code  
  2.   
  3. code segment  
  4.   
  5. start:  mov ax,bx  
  6.     mov si,offset start  
  7.     mov di,offset s  
  8.       
  9.     mov ax,cs:[si]  
  10.     mov cs:[di],ax  
  11.       
  12. s:  nop  
  13.     nop  
  14. code ends  
  15.   
  16. end start  


 

2. 依据位移进行转移的jmp指令

 

(1)jmp short 标号

 

 

是段内短转移。

表示转移到指定的标号处,且转移的距离范围为-128~127

 

用debug查看此指令时,会看见机器码,不会保存标号的地址,自会保存转移的距离

 

 

(2)jmp near ptr 标号

 

是段内近转移,转移的距离范围为-32768~32767,其他与jmp short 标号相同

 

2. 转移地址在寄存器中的jmp指令

 

jmp 16位 reg

 

表示 (IP)=(16位 reg)

 

3.转移地址在内存中的jmp指令

 

(1)jmp word ptr 内存单元地址

 

是段内近转移。

 

例子:转移到偏移地址为0123H的指令去,即使(IP)= 0123H

 

  1. mov ax,0123H  
  2. mov ds:[0],ax  
  3. jmp word ptr ds:[0]  

 

(2)jmp dword ptr 内存单元地址

 

 

是段间转移

 

高地址表示转移的段地址

低地址表示偏移地址

 

用debug查看机器码,可以发现,它是保存了段地址与偏移地址,而不是像段内转移的指令时保存转移的距离

 

例子:转移到段地址为0,偏移地址为0123H的指令去,即使得(CS)= 0,(IP)= 0123H

 

  1. mov ax,0123H  
  2. mov ds:[0],ax  
  3. mov word ptr ds:[2],0  
  4. jmp dword ptr ds:[0]  

 

 

 

4. jcxz 指令

 

 

jcxz 指令为条件转移指令。当cx为0时,转移(与loop刚刚相反)。所有条件转移指令都是短转移。

 

例子:在内存2000H段中查找第一个值位0 的字节,并把它的偏移指定存储在dx中。

 

  1. assume cs:code  
  2.   
  3. code segment  
  4.   
  5. start:  mov ax,2000H  
  6.     mov ds,ax  
  7.     mov bx,0  
  8. s:  mov ch,0  
  9.     mov cl,[bx]  
  10.     jcxz ok  
  11.     inc bx  
  12.     jmp short s  
  13. ok: mov dx,bx  
  14.     mov ax,4c00H  
  15.     int 21H  
  16. code ends  
  17. end start  


 

5. jmp指令详细分析

 

jmp s

jmp short s

jmp near ptr s

jmp far ptr s

 

向前转移:

在像前转移时,编译器可以在读到标号s后记下AC(地址计算器)的值as,在读到jmp ...s (上面5种)后记下AC的值aj。编译器可以用as-aj计算出disp

 

(1)如果disp 在 -128~127 内

上面的每一种指令都将转化为 jmp short s

(2)如果disp 在 -32768~32767 内

对于jmp short s会编译错误

对于jmp s,jmp near ptr s会产生jmp near ptr s所对应的机器码。

对于jmp far ptr s,所对应的机器码为:EA 偏移地址 段地址。

 

 

先后转移:

由于不能确定s位置,编译器先将上面的指令都当做 jmp short s来读取。记下jmp ..s 指令的位置和AC的值aj。

对于jmp short s 编译器生成一个EB和一个nop指令

对于jmp near ptr s 编译器生成一个EB和两个nop指令

对于jmp far ptr s 编译器生成一个EB和四个nop指令

 

当读到s时,记下AC的值as,计算disp = as - aj

(1)如果disp 在 -128~127 内

指令都为 EB disp ,它们后面的一个nop变成8位的disp 。jmp s(1个)、jmp near ptr s (1个)跟jmp far ptr s (3个) nop指令不变

(2)如果disp 在 -32768~32767 内

对于jmp short s会编译错误

jmp s、jmp near ptr s 后面 两个nop变成转移的16位disp。

jmp far ptr s 这填上相应的段地址,偏移地址。

 

6. 分析一个奇怪的程序

 

  1. assume cs:code  
  2.   
  3. code segment  
  4.       
  5.     mov ax,4c00h  
  6.     int 21h  
  7.           
  8. start:  mov ax,0  
  9. s:  nop  
  10.     nop  
  11.       
  12.     mov di,offset s  
  13.     mov si,offset s2  
  14.     mov ax,cs:[si]  
  15.     mov cs:[di],ax  
  16.       
  17. s0: jmp short s  
  18.       
  19. s1: mov ax,0  
  20.     int 21h  
  21.     mov ax,0  
  22.       
  23. s2: jmp short s1  
  24.     nop  
  25.       
  26. code ends  
  27.   
  28. end start  
  29.       

追后程序会运行s处的

mov ax,4c00h

int 21h

而正常终止。

为什么?

debug可以发现,jmp short s1 复制到s处后,由原来的jmp 0018H变成 jmp 0000H。

但是本质的机器码是EBF6没变就是ip = ip - 10。



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
ADI 高精度低功耗精密放大器