第十章 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)