call和ret

在这里插入图片描述
内存的物理地址最低总是从0开始。指针指向的最低应该也是0,所以一个四字节的指针应该是指向零字节到第三个字节

3.7.1-3.7.2
过程:
1.数据(以过程参数和返回值的形式)传递。
2.控制转移
3.分配和释放新过程中的局部变量

函数栈有底(高地址)和顶(低地址,会变化,向下延伸)。

%ebp指向最上面,帧指针(在一个过程执行过程中不变,代表帧开始)
由于帧指针不动,所以大部分信息的访问是针对帧指针的。
%esp指向最下面,栈指针(会随着过程中的指令变化而变化,代表动态变化的栈)

要调用新函数,需要保存上一个函数的返回地址(PC,程序计数器)和%ebp的值
上一个函数的返回地址保存在新函数%ebp+4的位置
上一个函数的%ebp值保存在新函数的%ebp中

和过程调用和返回有关的三个汇编指令
call
leave
ret

考虑一个函数调用过程,必然要改变PC,同时要保存返回地址。
所以call sumaddr的效果是:
1.push %eip+4 将返回地址(紧跟在call后面的那条指令的地址)入栈
2.movl sumaddr, %eip 改变%eip的值,跳转到被调用过程的开始。

接着执行
push %ebp 这个语句是sum过程的第一句
(后面应该还有一句movl %esp, %ebp 设置新的ebp值)

leave的效果是重设栈指针和帧指针:
movl %ebp, %esp 把esp的值设为ebp,连同后面两个pop的目的是为了恢复main的栈指针
popl %ebp 取出被保存的main的ebp值。返回地址在%ebp+4处,所以将返回地址(正好是main的%ebp)存入%ebp

ret的效果是
1.popl %eax 从栈中弹出返回地址,
2.movl %eax, %eip 跳转到这个返回地址

注:call和ret的操作汇编代码只是为了说明做了什么

只有call和ret能改变%eip的值

三对对应操作:
1.调用时用call改变eip的值后面也会用ret改回来
2.保存返回地址和帧指针的push操作最后会由对应的两个pop操作还原
3.leave的movl %ebp, %esp是对sum操作过程加了无数中间局部变量状态的一个还原。应该是和movl %esp, %ebp构成对应关系。

寄存器使用惯例:
调用者保存寄存器:%eax、%edx、%ecx。可以随便覆盖
被调用者保存寄存器:%ebx、%esi、%edi。若使用,必须恢复现场

学了忘,忘了学。。。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值