函数的简单调用过程

ebp和esp指针来标识一个函数的栈底和栈顶 main -> add(int a, int b)

  1. 从右向左把add函数的实参入栈
  2. 把call指令的下一行指令地址压入栈
  3. -这里要简单说一下变量的含义。ebp 和 esp 是两个通用寄存器。它们可以存储 立即数 和 内存地址。esi是源变址寄存器。edi是目的变址寄存器。 它们都可用来储存地址。
    在main()函数之前有一个函数CRTStartUp,ebp为这个函数的栈底,esp为这个函数的栈顶。

在这里插入图片描述
在这里插入图片描述
4. push ebp 把main函数栈底地址入栈
5. mov ebp, esp 让ebp指针指向sum函数的栈底大概变成如下如下
在这里插入图片描述
6. sub esp, 04Ch ,sub是减法指令,这句话使得esp向后移动了0E4h个单位相当于给函数开辟了栈帧。 接下来的三句话,是将ebx,esi,edi压入了栈当中。
lea 的意思是load effective address,也就是将[ebp - 0E4h]的地址取出来,赋值给了edi。
将39h赋值移动到ecx。将内容赋值移动给eax。
rep stos 是重复拷贝数据
7. ecx寄存器是用来保存复制粘贴的次数,ecx是计数器。
eax寄存器是用来传送信息的,eax是累加器,通常用来存储数据。
rep 是重复上述指令。
stos 是将eax的值赋值移动给 es:[edi]这个地址的存储单元。

rep stos指令(for) 给ebp<->esp之间的栈内存初始化0xCCCCCCCC(VS上做 GCC&G++不做栈的初始化)

  1. 执行sum函数的指令,直到右括号处

在这里插入图片描述

  1. 首先,我们创建了变量 ptr[z]。然后,将ptr[x]的值放在eax里边,将ptr[y]的值与eax相加后再放在eax里,将eax的值赋值移动到 ptr[z]中。最后,我们需要return z。这个地方编译器再次将ptr[z]的值赋值移动到了eax。这么做的原因是:ptr[x]、ptr[y]、ptr[z]将在函数完成后就会销毁,但是寄存器eax不会被销毁,所以在eax的值非常安全。
    在这里插入图片描述

10.mov esp, ebp 让esp指向add的栈底
11. pop ebp 出栈(main函数栈底地址),把出栈的值赋给ebp,ebp就指向了main函数栈底 因为
出栈,esp+=4
12. ret 出栈(下一行指令地址),赋给CPU的PC寄存器
在这里插入图片描述
13. esp += 8 把main函数的形参内存释,放现在esp + 8向高地址进发了。其目的就是消去了形参实例化的a,b。
14. 我们将eax里保存的数据赋值移动给了c。最后,xor异或,自己和自己异或 其值变为0。
15. 之后我们到了cmp指令,cmp是比较指令。它的操作是拿第一个数减去第二个数,如果相减为ZF=0说明相等。但是cmp并不会真的减.
16. 依次出栈main函数销毁完成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值