《汇编语言》– 转移指令的原理 CALL和RET指令

转移指令的原理

 

①:可以修改IP,或同时修改CS和IP的指令称为转移指令。

8086CPU的转移行为有以下几类。

只修改IP时,称为段内转移,比如:jmp ax。

同时修改CS和IP时,称为段间转移,比如:jmp 1000:0.

由于转移指令对IP的修改范围不同,段内转移又分为:短转移和近转移。

短转移IP的修改范围为-128-127.

近转移IP的修改范围为-32768-32767.

8086CPU的转移指令分为以下几类:

1.无条件转移指令

2.条件转移指令

3.循环指令 loop

4.过程

5.中断

 

②:操作符offset在汇编语言中是由编译器处理的符号,它的功能是取得符号的偏移地址。

codesg segment

start:mov ax,offset start               ;相当于 mov ax,0

       s:mox ax,offset s                     ;相当于 mov ax,3

codesg ends

 

③:jmp short 标号(转到标号处执行指令)

这种格式的jmp指令实现的是段内短转移,它对IP的修改范围为-128~127。

CPU在执行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 标号 实现的是段间转移,又称为远转移。汇编代码是包括转移的目的地址的。

jmp 16位reg    功能:  (IP) = (16位reg)

 

转移地址在内存中的jmp指令有两种格式:

1.jmp word ptr 内存单元地址(段内转移)

功能:从内存单元地址处开始存放着一个字,是转移的目的偏移地址。

 

2.jmp dword ptr 内存单元地址(段间转移)

功能:从内存单元地址处开始存放着两个字,高地址处的字是转移的目的段地址,低地址处是转移的目的偏移地址。

(CS) = (内存单元地址+2)

(IP) = (内存单元地址)

 

④:jcxz指令为有条件转移指令,所有的有条件转移指令都是短转移,在对应的机器码中包含转移的位移,而不是目的地址。对IP的修改范围都为-128-127.

指令格式:jcxz标号(如果(cx)=0,转移到标号处执行。)

操作:当(cx)=0时,(IP)=(IP)+8位位移;

8位位移=标号处的地址-jmp指令后的第一个字节的地址;

8位位移的范围-128-127,用补码表示;

8位位移由编译程序在编译时算出。

 

功能:

if((cx)==0) jmp short 标号

 

⑤:loop指令为循环指令,所有的循环指令都是短转移,在对应的机器码中包含转移的位移,而不是目的地址。对IP的修改范围都为-128-127.

指令格式:loop标号((cx)=(cx)-1,如果(cx)!=0,转移到标号处执行。)

操作:

1.(cx)=(cx)-1;

2.如果(cx)!=0,(IP)=(IP)+8位位移;

8位位移=标号处的地址-loop指令后的第一个字节的地址;

8位位移的范围-128-127,用补码表示;

8位位移由编译程序在编译时算出。

 

如果(cx)=0,什么也不做(程序向下执行)

 

功能:

(cx)—;

if((cx)!=0) jmp short 标号;

 

CALL和RET指令

 

①:ret指令用栈中的数据,修改IP的内容,从而实现近转移;

retf指令用栈中的数据,修改CS和IP的内容,从而实现远转移。

 

CPU执行ret指令时,相当于进行:

pop IP

CPU执行retf指令时,相当于进行:

pop IP

pop CS

 

②:CPU执行call指令时,进行两步操作:

1.将当前的IP或CS和IP压入栈中;

2.转移。

 

相当于:

push IP

jmp near ptr 标号

 

call far ptr 标号 实现的是段间转移。

相当于:

push CS

push IP

jmp far ptr 标号

 

call 16 位reg 相当于:

push IP

jmp 16位reg

 

call word ptr 内存单元地址:

push IP

jmp word ptr 内存单元地址

 

call dword ptr 内存单元地址:

push CS

push IP

jmp dword ptr 内存单元地址

 

③:mul是乘法指令

1.两个相乘的数:两个相乘的数,要么都是8位,要么都是16位。如果是8位,一个默认放在AL中,另一个放在8位reg或内存单元中;如果是16位,一个默认放在AX中;另一个放在16位reg或内存单元中。

2.结果:如果是8位乘法,结果默认放在AX中;如果是16位乘法,结果高位默认在DX中存放,低位在AX中存放。

 

mul byte ptr ds:[0]

含义:(ax) = (al)*((ds)*16+0)

mul word ptr [bx+si+8]

含义:(ax) = (ax)*((ds)*16+(si)+8)  结果的低16位

            (dx) = (ax)*((ds)*16+(si)+8)  结果的高16位

 

④:定义以0结尾的字符串

db  ‘string’,0

 

解决寄存器冲突的方法:

在子程序的开始将子程序中所有用到的寄存器中的内容都保存起来,在子程序返回前再恢复,注意寄存器入栈和出栈的顺序!

 

BY:AloneMonkey

本文链接:http://www.alonemonkey.com/masm-chapter910.html