我对以下代码中的 EBP、ESP 和堆栈框架有一些疑问。
为什么我们从 esp 中减去 28?我们在 main 中有两个局部变量 x 和 y。那么为什么我们不减去 8 呢?
而且我们不是将值从右(或顶部)到左(或底部)放入堆栈吗?那么为什么我们在 [eax+8] 中加 1 而不是 [eax+4] 呢?
func(int a, int b, int c)
{
return a+b+c;
}
main()
{
int x, y=3;
x=func(y,2,1);
}
我对以下代码中的 EBP、ESP 和堆栈框架有一些疑问。
为什么我们从 esp 中减去 28?我们在 main 中有两个局部变量 x 和 y。那么为什么我们不减去 8 呢?
而且我们不是将值从右(或顶部)到左(或底部)放入堆栈吗?那么为什么我们在 [eax+8] 中加 1 而不是 [eax+4] 呢?
func(int a, int b, int c)
{
return a+b+c;
}
main()
{
int x, y=3;
x=func(y,2,1);
}
堆栈指针减去 28,因为两个局部变量需要 8 个字节,函数参数需要 12 个字节。额外的 8 个字节可能是由于您的编译器尝试将 main 的堆栈与 16 字节边界对齐(堆栈上已经有 4 个字节用于 main 的返回地址,而当 EBP 被推送以在 main 的第一条指令中建立堆栈帧时,另外 4 个字节)。如果您使用 GCC,请参阅-mpreferred-stack-boundary 。
参数从右到左传递。由于堆栈空间在从堆栈指针中减去时已经分配给三个参数,因此将 1 移动到相对于当前堆栈指针的“最高”位置(+8),将 2 移动到中间(+4) ,并且 y 中的值被移动到堆栈指针本身。这与将 1 压入堆栈,将 2 压入堆栈,然后将 y 压入堆栈相同。通过最后一个 push 指令,1 是来自 ESP 的 +8,2 是来自 ESP 的 +4,y 是来自 ESP 的 +0。请注意,在 func 内部,它必须将这些偏移量加 8,因为返回地址是从 call 指令压入堆栈,而 func 会压入 EBP 以建立堆栈帧。
对哪种结构感到困惑?