call和ret指令

146 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。 目录

image.png  

call 和 ret都是转移指令,它们都修改IP,或同事修改CS和IP

 

10.1 ret和retf

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

 

CPU执行ret指令时进行如下操作

image.png  

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

image.png CPU执行ret相当于pop IP

执行retf相当于pop IP

pop CS

image.png

 

ret测试

这边将ax的值推入栈中

ret相当于pop IP

即把ax的值给了IP(0)

后执行mov ax ,4c00h

int 21h

程序终止

 

image.png  

 

retf测试

相当于pop IP

pop cs

 

image.png  

10.2 call指令

call 指令经常与ret指令配合使用,因此CPU执行call指令,进行两步操作:

image.png

 

call 标号

16位位移

image.png

image.png

 

10.3 依据位移进行转移的call指令

E8是call的机器码

05是偏移

image.png (1)当前IP压入栈

注意:此处IP是读取完call s指令后,为05h

(2)转到标号处执行指令

 

 

10.4转移的目的地址在指令中的call指令

之前的call只是相对于当前IP的转移位移

 

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

CPU执行的操作

image.png  

 

 

10.5转移地址在寄存器中的call指令(实现短转移)

call 16位寄存器

image.png  

 

10.6 转移地址在内存中的call指令

image.png

 

call word ptr 内存单元地址(IP,近转移)

image.png

 

call dword ptr 内存单元地址(CS和IP,段间跳转)

image.png

image.png

 

高16位存放CS,低16位存放IP

 

 

10.7 call和ret的配合使用

image.png

bx=8

 

10.7call和ret的配合使用2

image.png  

 

小结:

可以写一个具有一定功能的程序段,我们称之为子程序,在需要的时候,用call指令转去执行。子程序调用完之后再ret返回接着call指令向下执行

 

 

在C语言中实例使用:

image.png

 

image.png

调用printf函数

 

 

 

image.png

此时CPU跳转至love函数

image.png

love函数的结尾

返回至call指令接下来执行指令

 

 

10.8 mul指令

相乘的两个数:要么都是8位,要么都是16位

 

image.png

结果的存放

image.png

格式

mul reg

mul 内存单元

 

ATTENTION:

如果是八位乘上十六位

这边建议把八位强制转换成16位(填充0)

 

eg:

image.png

8位乘8位

image.png

 

8位乘16位(8位填充乘成16位)

image.png  

 

Conclusion:

call和ret指令共同支持了汇编的模块化设计。程序的模块化设计必不可少

 

 

10.10 参数和结果传递的问题

一个参数

可用寄存器bx来存放参数

结果存放到dx和ax中

image.png

 

N个参数

可将批量数据存放到内存中

eg

放到内存中

image.png

 

 

10.12寄存器冲突的问题

实例

image.png  

image.png  

image.png jcxz检验循环是否完成

若完成了直接跳转至ok,ret返回call接下来执行指令