call指令和ret指令【笔记+详解】

这篇具有很好参考价值的文章主要介绍了call指令和ret指令【笔记+详解】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

call指令和ret指令【笔记】

1 引子

   在高级语言中,常有主程序调用其他子程序,子程序还可以调用子程序…,比如在C语言中,在main主函数里调用cube函数,该函数被执行完后返回main函数,然后程序继续往下执行,如下:

#include <stdio.h>
int main(){
	int cube();//函数的声明
	int a = cube();//调用函数
	...
	return 0;
}
//定义函数
int cube(){
	printf("hello");
	return 10;
}

  在汇编语言中也有类似的这种机制,能实现主程序调用子程序。这就要使用call和ret汇编指令

2 call和ret的简单运用

2.1功能简述
  call指令可以实现调用一个子程序,在子程序里使用ret指令结束子程序的执行并返回主程序(类比C语言中的main函数调用cube函数进行理解),主程序继续往下执行。

2.2指令格式

  • call 标号 或者call far 标号
  • ret 或者 ret n

2.3标号位数

  • 16位位移=”标号所在偏移地址“ - call指令的下一条指令的偏移地址
  • 16位位移的范围"-32768~32767",补码表示

2.4示例:(”;“符号是8086汇编的注释符)

...
mov ax,0
call s     ;s是标号,执行call后,执行s标号所在的子程序
mov ax,4c00h
int 21h

s:add ax,1             ;标号所在子程序
  mov bx,10
  ret                        ;子程序执行完后,返回主程序

3 call指令本质含义详解

3.1实质:call指令是一个流程转移指令,就是让程序执行的顺序发生短暂的改变,去执行别处地址上的指令,遇到ret指令后再回到原来的地方继续往下顺序执行,本质和jmp大同小异,区别是在jmp基础上增加了程序回到原来跳转处的功能。

3.2call执行步骤:(cpu执行call指令)

  • 第一步:将当前的ip或者cs和ip压入栈中。即跳转前保存call指令的下一条指令的首地址
  • 第二步:转移到标号处执行子程序。即修改ip或者cs和ip里的内容(对比jmp详解篇理解)

第一步分析
先看一个汇编源程序

assume cs:code,ss:stack
stack segment
	db 8 dup (0)
stack ends
code segment
start:	mov ax,stack
		mov ss,ax
		mov sp,8
		call s
		mov ax,0
		mov ax,4c00h
		int 21h
	s:	mov bx,0
		add bx,1
		ret
code ends
end start

编译后对应的机器码和汇编指令
ret指令,学习,汇编,编辑器
知道call指令的下一条指令的偏移地址是000B,即取call指令完后ip的内容就为000B,紧接着执行call指令,由第一步知晓执行call指令时,当前的ip或者cs和ip压入栈中。
备注:cpu执行一条指令分为两步(t命令):1.取指令、2.执行指令
我们再来看一下执行call指令之前栈段里的内存情况
ret指令,学习,汇编,编辑器
此时栈里发现有数据(p指针左边的一个字的数据是”01A3“,这个数当作随机数处理)先不管这些数据,我们看到ip的值为”0008“,到目前为止只是执行call指令之前的代码,并未对栈里添加数据。接下来我们执行call指令,然后再观察栈顶数据,如下
ret指令,学习,汇编,编辑器
发现栈顶的数据已经变为000B(这地址是call指令的下一条指令首地址,上文提到过),可能会想入栈的数据不是执行call指令时,当前的ip(图2中绿色划线)或者cs:ip(这里不讨论该种情况)的内容吗?,但别忘了,执行一条指令后,本该就要执行下一条指令(即ip=ip+指令长度,所对应的指令的,它就是call的下一条指令,因此ip变为000B),ip自增后发现执行的是call指令,然后进行第一步的入栈操作。(call指令还未完全执行)

接着分析第二步
  此时ip=000B,按理来说要执行ip=000B处的指令,但call指令的目的不就是使指令跳转吗,因此它还要修改ip为目的地的偏移地址,所以ip=0013(标号或目的地所在的偏移地址)。从而call指令实现,当前地址的保存(实质是下一条指令的首地址入栈)和程序的跳转。

4 ret指令

  理解call指令,ret指令就很容易明白,执行ret指令时,会把栈中原先存入的地址出栈,并送入到ip寄存器里,ret指令等价于”pop ip“的效果(没有pop ip这样的指令,是非法的

5 总结及汇编环境资源

指令格式 示例
call 标号 -仅仅修改ip,修改范围一个字
call 16位寄存器 -等价于call 标号
call far ptr 标号 -同时修改cs和ip,段间转移(调用子程序),先把cs入栈再把ip入栈
call word ptr 内存单元地址 -仅修改ip,段内转移,例如:… ptr ds:[idata]
call dword ptr 内存单元地址 -同时修改cs和ip,段间转移,先把cs入栈再把ip入栈,例如:…ptr ds:[idata]会把以idata为起始地址,长度为两个字的内存单元取出来,低地址的字单元存放偏移地址,高地址的字单元存放段地址。
ret -把原先压入栈的ip内容进行出栈,并送入ip中,等价于pop ip
retf -把原先压入栈的cs和ip出栈,同时修改ip和cs,先修改出栈ip再出栈cs,等价于:
– pop ip
– pop cs
ret n - n是任意取的数字,一般n为栈中除开ip或者cs和ip数据外的其他数据占用的字节单元数,表示忽略栈中的数据,把栈顶指针移动到栈底。

备注:没有pop ip这样的指令,是非法的,笔记中仅是为了方便理解而使用

8086汇编环境资源免费获取【DOSBox】
链接:https://pan.baidu.com/s/1aRv4k6DVlJtGkHQDB6WjrA
提取码:8086文章来源地址https://www.toymoban.com/news/detail-773054.html

到了这里,关于call指令和ret指令【笔记+详解】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux:环境搭建、基本指令操作、Vim 编辑器的使用

    Linux 是一套 免费使用 和 自由传播 的类 Unix 操作系统,是一个基于 POSIX(可移植操作系统接口)和 UNIX 的 多用户 、 多任务 、 支持多线程 和 多 CPU 的操作系统; Linux 是一个操作系统, 操作系统本身也是一个软件 ; Linux 能运行主要的 UNIX 工具软件、应用程序和网络协议,

    2024年01月25日
    浏览(41)
  • vi编辑器的三种模式及其对应模式下常用指令

    vi是Linux系统的第一个全屏幕交互式编辑工具,在嵌入式的 学习中是一个不可或缺的强大的文本编辑工具。 命令模式 如何进入命令模式:按esc键 复制:yy nyy(n:行数) 删除(剪切): dd ndd 粘贴:p 撤销:u 反撤:ctrl r 光标移动首行: gg 光标移动末行: G 光标移动行尾:$ 光标跳到

    2024年02月03日
    浏览(48)
  • 『Linux从入门到精通』第 ⑥ 期 - Linux编辑器——vim(最小集+指令集+自动化配置)

    目录 💐专栏导读 💐文章导读  🌷vim最小集 🌺vim的三种模式 🌺vim的基本操作 🌷vim指令集 🌺命令模式指令集 🌼移动光标 🌼删除文字 🌼复制 🌼替换 🌼撤销上一次操作 🌼更改 🌼跳至指定的行 🌺底行模式指令集 🌼列出行号 🌼跳到文件中的某一行 🌼查找字符 🌼保

    2024年01月24日
    浏览(41)
  • 【ARM64 常见汇编指令学习 13 -- ARM 汇编 ORG 伪指令学习】

    上篇文章:ARM64 常见汇编指令学习 12 – ARM 汇编函数 的学习 下篇文章:ARM64 常见汇编指令学习 14 – ARM 汇编 .balign,.balignw,.balign 伪指令学习 在ARM汇编中,\\\" org \\\"是一个汇编器伪指令,用于设置下一条指令的装入地址。\\\" org \\\"后面跟着的是一个表达式,这个表达式的值就是下一条

    2024年02月14日
    浏览(34)
  • 【ARM64 常见汇编指令学习 14 -- ARM 汇编 .balign,.balignw,.balign 伪指令学习】

    上篇文章:ARM64 常见汇编指令学习 13 – ARM 汇编 ORG 伪指令学习 下篇文章:ARM64 常见汇编指令学习 15 – ARM 标志位的学习 .balignl 是一个伪操作符,伪操作符的意思就是机器码里,并没有一个汇编指令与其对应,是编译器来实现其功能的。. balignl 是 .balign 的变体。 .balignl 完整

    2024年02月14日
    浏览(31)
  • CTF学习笔记——ret2text

    ret2text 应该算是PWN里面比较简单的题型了,这种题型有个显著特征,就是会有个很明显的后门函数,也就是 system(\\\"/bin/sh\\\") ,我们只需要将我们的程序跳转到后门函数即可。不过我们控制执行程序已有的代码的时候也可以控制程序执行好几段不相邻的程序已有的代码 (也就是

    2024年02月04日
    浏览(29)
  • 【ARM 常见汇编指令学习 5 -- arm64汇编指令 wzr 和 xzr】

    上篇文章:ARM 常见汇编指令学习 4 – ARM64 比较指令 cbnz 与 b.ne 区别 下篇文章:ARM 常见汇编指令学习 6 - bic(位清除), orr(位或), eor(异或) ARMv8 在硬件层名引入了一个新的 zero 寄存器 : XZR (64-bits), WZR (32-bits)。比如要将某一变量赋值为0x0, 由于ARM不允许直接操作内存单元上的数据

    2024年02月15日
    浏览(43)
  • vim编辑器用法详解

    Vim(Vi IMproved)是一个功能强大的文本编辑器,是Vi(Visual Editor)的一个增强版本。它以其高度可定制性、强大的编辑功能和广泛的插件支持而闻名。这里介绍一下Vim编辑器的那些使用技巧,熟练使用这些技巧可以大大提升在Linux品台下文本编辑的效率。 Linux 下安装 Windows下安装包

    2024年02月12日
    浏览(39)
  • 【ARM64 常见汇编指令学习 12 -- ARM 汇编函数 的学习】

    上篇文章:ARM64 常见汇编指令学习 11 – ARM 汇编宏 .macro 的学习 下篇文章:ARM64 常见汇编指令学习 13 – ARM 汇编 ORG 伪指令学习 ARM汇编中的函数定义并不像高级语言那样有特定的语法,但通常可以通过 标签(label) 和 子程序调用指令 (如BL,BLX) 来实现类似于函数的功能。 例如

    2024年02月14日
    浏览(35)
  • ARM汇编寄存器和常用指令详解

    对于32位及其以下的ARM处理器来说,函数调用规则如下: 父函数与子函数的入口参数以此通过 R0~R3 这4个寄存器传递。 父函数在调用子函数前先将子函数入口参数存入 R0~R3 寄存器中,若只有一个入口参数则使用 R0 寄存器传递,若有2个入口参数则使用 R0 和 R1 寄存器传递,以

    2024年02月03日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包