汇编学习笔记(6)转移指令原理

这一章主要介绍了转移指令jmp的实现原理,个人感觉还是比较重要的一章,这一章就详细摘录书上的例题及练习,已达到巩固的效果。

offset

offset是由编译器执行的指令并没有对应的机器码。

  • 语法:offset 标号

  • 功能:获取标号的偏移地址

书上的例子

 1 ;offset
 2 
 3 assume cs:codesg
 4 
 5 codesg segment
 6     
 7 start:  mov ax,offset start
 8 s:      mov ax,offset s
 9 
10         mov ax,4c00h
11         int 21h
12  
13 
14 codesg ends
15 end start

 

可以看到,标号offset偏移地址为0它是第一条指令,标号s的偏移地址为3,这是因为mov ax,offset start占用了三个字节。

jmp

转移指令是指可以修改IP,或同时修改IP和CS的指令。

  • 段内转移:只修改IP的值,又分为短转移和近转移。短转移是值IP的修改范围在-128~127之间(内存单元的储值范围),近转移是指IP的修改范围在-32768~32767(寄存器的储值范围)之间。

  • 段间转移:同时修改CS和IP的值。

jmp指令的格式(目前所学):

1.jmp short 标号:段内短转移

2.jmp near ptr 标号:段内近转移

3.jmp far ptr 标号:段间转移

4.jmp 寄存器:段内转移

5.jmp word ptr 内存单元:段内转移

6.jmp dword ptr 内存单元:段间转移

jmp short 标号

书上的例子

 1 ;jmp short 标号
 2 
 3 assume cs:codesg
 4 
 5 codesg segment
 6     
 7 start:  mov ax,0
 8         jmp short s
 9         add ax,2
10 s:      inc ax
11 
12         mov ax,4c00h
13         int 21h
14  
15 
16 codesg ends
17 end start

 

从上图可以看出,jmp short s已被翻译成jmp 0008即jmp标号s的偏移地址,而对应的机器码为EB03。

jmp short s执行时不需要目的地的地址,只需要应转移的位移即可,过程是这样的:

1.(CS)=076AH,(IP)=0003H,CS:IP指向jmp short s(EB03)

2.读取指令EB03至指令缓冲器,(ip)=(ip)+2(加2是因为jmp short s指令长度为2字节),(ip)=0005H

3.执行指令EB03向后3个字节,(ip)=(ip)+3,(ip)=0008H

这是向后转移的例子,我们再来做个向前转移的例子

 1 ;jmp short 标号
 2 
 3 assume cs:codesg
 4 
 5 codesg segment
 6     
 7 start:  mov ax,0
 8 s:      inc ax
 9         add ax,2
10         jmp short s
11 
12         mov ax,4c00h
13         int 21h
14  
15 codesg ends
16 end start

 

jmp short s这次过程是这样的:

1.(CS)=076AH,(IP)=0007H,CS:IP指向jmp short s(EBFA)

2.读取指令EBFA至指令缓冲器,(ip)=(ip)+2(加2是因为jmp short s指令长度为2字节),(ip)=0009H

3.执行指令EBFA向前6个字节,(ip)=(ip)-6,(ip)=0003H

EBFA表示向前6个字节由补码解释,6H=00000110B,取反+1为11111010B=FAH,有以上两个程序可知jmp指令的位移等于标号处的偏移地址-jmp指令的下一条指令的偏移地址,看上去挺绕的,减去下一条指令的地址是因为在CPU执行指令前先将ip加上jmp的指令长度,所以要减去jmp指令的长度。

jmp short s只可以转移-128~127的范围那超出会怎样呢?试下就知道了

 1 ;jmp short 标号
 2 
 3 assume cs:codesg
 4 
 5 codesg segment
 6     
 7 start:  mov ax,0
 8         jmp short s
 9         db 128 dup(1)
10 s:      inc ax
11 
12         mov ax,4c00h
13         int 21h
14  
15 codesg ends
16 end start

 

很明显,编译时报错超出1字节

jmp near ptr 标号

jmp near ptr和jmp short 功能相似只不过范围变成了-32768~32767

jmp far ptr 标号

(CS)=标号所在段的段地址,(ip)=标号在段中的偏移地址

 1 ;jmp far ptr 标号
 2 
 3 assume cs:codesg
 4 
 5 codesg segment
 6     
 7 start:  mov ax,0
 8         jmp far ptr s
 9         db 128 dup(1)
10 s:      inc ax
11 
12         mov ax,4c00h
13         int 21h
14  
15 codesg ends
16 end start

机器码EA88006A07,其中低位8800偏移地址,高位6A07为段地址即(cs)=076AH,(IP)=0088H.

jmp 寄存器

8086COU是16位寄存器,所以jmp 寄存器所能转移的范围为-32768~32767,属于段内转移。

jmp word ptr 内存单元

word是字型数据占2个字节,所以能转移的范围为-32768~32767,属于段内转移,将内存单元开始的字型数据赋给IP。

jmp dword ptr 内存单元

dword是双字型数据占4个字节,所以高地址处的字型数据是段地址,低地址处的字型数据是偏移地址。

 1 ;jmp dword ptr
 2 
 3 assume cs:codesg
 4 
 5 codesg segment
 6     
 7 start:  mov ax,0123h
 8         mov ds:[0],ax
 9         mov bx,0
10         mov ds:[2],bx
11         jmp dword ptr ds:[0]
12 
13         mov ax,4c00h
14         int 21h
15  
16 codesg ends
17 end start

 

jcxz

jcxz 标号表示当cx等于0时转移到标号处执行。

if((cx)==0)

  jmp short 标号

posted @ 2013-12-26 22:51  huntstack  阅读(388)  评论(0编辑  收藏  举报