第十章 CALL和RET指令
call
和ret
指令都是转移指令,它们都修改CS和IP。经常被共同用于实现子程序的设计。这一章,我们讲解call
和ret
指令的原理
10.1 ret和retf
-
ret
指令用栈中的数据,修改IP的内容,从而实现近转移- (IP)=((ss)*16+(sp))
- (sp)=(sp)+2
- 等于 pop IP
-
retf
指令用栈中的数据,修改CS和IP的内容,从而实现远转移- (IP)=((ss)*16+(sp))
- (sp)=(sp)+2
- (IP)=((ss)*16+(sp))
- (sp)=(sp)+2
- 等于 pop IP,pop CS
10.2 call指令
CPU执行call
指令时,进行两步操作:
- 将当前的
IP
或CS和IP
压入栈中 - 转移
call
指令不能实现短转移,除此之外,call与jmp类似。
接下来以转移地址的不同方式为主线,详解call指令
10.3 根据位移进行转移的call指令(段内转移)
- 格式:
call 标号
(压入栈,转移到标号) -
执行如下操作
-
(sp)=(sp)-2
((ss)*16+(sp))=(IP)
- (IP)=(IP)+16位位移
-
-
相当于
push IP
jmp near ptr 标号
10.4 根据目的的进行的call指令(段间转移)
格式:
call far ptr 标号
实现段间转移-
执行如下操作:
- (sp)=(sp)-2
- ((ss)*16+(sp))=(CS)
- (sp)=(sp)-2
- ((ss)*16+(sp))=(IP)
- (CS)=标号所在段的段地址
- (IP)=标号所在段的偏移地址
-
相当于
push CS
push IP
jmp far ptr 标号 注意先丢
CS
,再丢IP
10.5 转移地址在寄存器的call指令
- 格式:call 16位reg
-
功能
- (sp)=(sp)-2
- ((ss)*16+(sp))=(IP)
- (IP)=(16位reg)
-
相当于
push IP
jmp 16位reg
10.6 转移地址在内存的call指令
-
call word ptr 内存单元地址
-
相当于
push IP
jmp word ptr 内存单元地址
-
-
call dword ptr 内存单元地址
-
相当于
push CS
push IP
jmp dword ptr 内存单元地址
-
10.7 call和ret的配合使用
- call 相当于 函数调用
- ret 相当于 return
10.8 mul指令(乘法)
mul 是乘法指令
必须都是8位,或是16位
- 8位:一个放在
AL
,另一个放在8位reg
或内存单元,结果放在AX
中 - 16位: 一个放在
AX
,另一个放在16位reg
或内存单元,结果高位放在DX
,低位放在AX
中
10.10 参数和结果传递的问题
- 用寄存器来存储参数和结果是最常使用的方法
10.11 批量数据的传递
- 将批量数据的首地址存入寄存器
- 返回数据的收地存入寄存器
10.12 寄存器冲突的问题
子程序开始:子程序中使用的寄存器入栈 子程序的内容 子程序中使用的寄存器出栈 返回(ret,retf)