汇编之call和ret指令
文章目录
call和ret指令
call和ret指令都是转移指令,它们都修改IP,或同时修改CS和IP。
1、ret 和 retf
- ret指令用栈中的数据,修改IP的内容,从而实现近转移;
- retf指令用栈中的数据,修改CS和IP的内容,从而实现远转移。
CPU执行ret指令时,相当于进行: pop IP
:
(1)(IP) = ( (ss) * 16 + (sp) )
(2)(sp) = (sp) + 2
CPU执行retf指令时,相当于进行:pop IP, pop CS
:
(1)(IP) = ( (ss) * 16 + (sp) )
(2)(sp) = (sp) + 2
(3)(CS) = ( (ss) * 16 + (sp) )
(4)(sp) = (sp) + 2
|
|
2、call 指令
call指令经常跟ret指令配合使用,因此CPU执行call指令,进行两步操作:
(1)将当前的 IP 或 CS和IP 压入栈中;
(2)转移(jmp)。
call指令不能实现短转移,除此之外,call指令实现转移的方法和 jmp 指令的原理相同。
call 标号
(近转移)
CPU执行此种格式的call指令时,相当于进行 push IP
jmp near ptr 标号
call far ptr 标号
(段间转移)
CPU执行此种格式的call指令时,相当于进行:push CS,push IP
jmp far ptr 标号
|
|
CPU执行此种格式的call指令时,相当于进行: push IP
jmp 16位寄存器
|
|
CPU执行此种格式的call指令时,相当于进行:push IP
jmp word ptr 内存单元地址
|
|
call dword ptr 内存单元地址
CPU执行此种格式的call指令时,相当于进行:push CS
push IP
jmp dword ptr 内存单元地址
|
|
3、call 和 ret 的配合使用
分析下面程序
|
|
call 与 ret 指令共同支持了汇编语言编程中的模块化设计,用来编写子程序
4、寄存器冲突
在设计子程序时,由于寄存器资源有限,难免会出现子程序和调用程序使用了同一个寄存器,而且子程序还修改了这个寄存器,那么这样就存在巨大的问题。如何解决呢?
其实,这个就类似于高级语言的函数调用。既然都要使用某个寄存器,那么就可以这样:当进入子程序时,我们将调用程序寄存器里的数据放到栈里面存放,这样子程序就可以放心使用啦。子程序结束之后,我们再将数据恢复到寄存器里即可。
文章作者 cold-bin
上次更新 2023-01-14