函数调用🍊
call 即 调用
为什么我们要记住这个地址呢?
在汇编语言中,"call"是一个指令,用于调用(跳转到)一个子程序或函数。它的作用是将程序的控制权转移到指定的子程序或函数,并在子程序或函数执行完毕后返回到调用它的地方。
这里调用的地址是是0x00401095
但是call指令还有一个作用:"call"指令会将下一条指令的地址(也称为返回地址)压入栈中,然后将控制权转移到目标地址。
就是这个地址,我们在调用完成后回来这,当然不要忘记我们要压这个地址入栈,先不用讲add,因为我们还要进入函数。
我们先给出Add函数汇编代码,让大家有个概念。这次我们才真正来到Add函数。
大家有没有发现和我们前面所讲解的main函数完全一样!
这就是在为Add函数准备它的函数栈帧。
我们为了加深印象还是简单的讲解
这是ebp初始的位置,
这就是这两行的意思。
44h是68(十进制)。
为了方便对比我将ebx,esi,edi的颜色是一样的。这个过程中esp也会多次移动。
这张大图很容易对比
然后是这个。
先初始化
然后就是——直接看图吧!
这就完全能够说明函数在传参过程中,真的会临时创建变量来接收,而我们之前的ecx,和eax就是接收实参,而且是先接收左边的b,再接收a。 然后在Add函数需要的时候借用这两个寄存器传过去。
当然还没有结束还要return!
我们再来观察
我就不在图上改了,这里就是相当于把eax的值变成30,很明显因为我们出函数时要销毁局部变量所以只能通过寄存器传递值。
pop(出栈)
"pop"是一个汇编指令,用于从栈中弹出(取出)一个值,并将其存储到指定的目标操作数中。
通常情况下,"pop"指令用于从栈中弹出一个值并将其存储到寄存器中。例如,"pop eax"将从栈中弹出一个值,并将其存储到eax寄存器中。
弹弹弹~ edi esi ebx
把 ebp 赋给esp
当然我们的Add函数也就没必要存在了
最后是
弹出ebp再并将其存储到ebp寄存器中。