代码
以下简单的x86汇编代码是CDECL调用约定的listed on Wikibooks:
功能定义:
_MyFunction1:
push ebp
mov ebp, esp
mov eax, [ebp + 8]
mov edx, [ebp + 12]
add eax, edx
pop ebp
ret
调用函数:
push 3
push 2
call _MyFunction1
add esp, 8
这是从以下C代码生成的内容:
_cdecl int MyFunction1(int a, int b)
{
return a + b;
}
此函数调用:
x = MyFunction1(2, 3);
问题
不幸的是,我无法完全围绕着这里发生的事情。从调用函数开始,这是我了解的事件列表:
- 将整数3推入堆栈
- 将整数2推入堆栈
- 调用_MyFunction1,将指令指针IP推入堆栈
- 将基本指针ebp推入堆栈,以便以后可以恢复它。我想这只是必要的,因为我们要在下一条指令中将值移到ebp中?
- 将当前堆栈指针esp的值移动到ebp中,以供以后在内存处理中使用。为什么这样为什么不直接在接下来的两条指令中使用esp的值(即[esp + 8],[esp + 12])
- 获取我们压入堆栈的两个整数值,并将它们保存在eax和edx中。显然,我们通过指向每个内存地址来实现。处理器如何知道直到完全读取例如它必须看多远。整数3?它怎么知道这里是32位还是16位整数?堆栈指针偏移量8和12的精确度如何?它们是什么意思,例如8代表8位偏移吗?
- 将两个值一起添加到eax中
- 从堆栈中恢复ebp
- 返回,即从堆栈中弹出包含下一条指令的eip并跳转到它
- 向堆栈指针esp加8(再次,是什么单位?)
- 现在,使用CDECL,调用者必须清理堆栈。我认为这是本指令所发生的。但是,简单地前进指针是如何清理堆栈的方法呢?从未弹出3和2整数值。如果有的话,我会以为减小指针值可以解决问题,而不像这里所做的那样增加它