【发布时间】:2015-09-18 04:25:48
【问题描述】:
我只是在学习一些程序的低级分析。在使用gcc进行32位编译时,发现栈帧的创建顺序如下:
- 以相反的顺序推送函数参数。
- 保存退货地址
- 保存帧指针
- 创建局部变量
所以参数的地址应该是最高的,因为堆栈以相反的顺序增长。但是当我尝试使用 64 位编译时,我无法理解它是如何创建的,这与我在 32 位编译中发现的相反。这是代码和内存详细信息:
void test(int a, int b, int c, int d)
{
int flag;
char buf[10];
num = 100;
}
int main()
{
test(1, 2, 3, 4);
}
现在为简单起见,我们只取参数和返回地址。
32 位编译:
0xffffd130: 0x00000001 0xffffd1f4 0xffffd1fc 0xf7e3ad1d
0xffffd140: 0xffffd158 0x0804842d 0x00000001 0x00000002
0xffffd150: 0x00000003 0x00000004 0x00000000 0xf7e22933
0xffffd160: 0x00000001 0xffffd1f4 0xffffd1fc 0xf7fdb6b0
0x08048421 <+30>: mov DWORD PTR [esp],0x1
0x08048428 <+37>: call 0x80483f0 <test>
0x0804842d <+42>: leave
这里一切正常。我可以在较高地址看到参数,紧接着是较低地址的返回地址0x0804842d。现在,
64位编译:
0x7fffffffdf80: 0x00000004 0x00000003 0x00000002 0x00000001
0x7fffffffdf90: 0x00400530 0x00000000 0x00400400 0x00000000
0x7fffffffdfa0: 0xffffdfb0 0x00007fff 0x0040052a 0x00000000
0x7fffffffdfb0: 0x00000000 0x00000000 0xf7a3baf5 0x00007fff
0x0000000000400525 <+24>: call 0x4004f0 <test>
0x000000000040052a <+29>: pop rbp
0x000000000040052b <+30>: ret
在这里我可以看到参数位于较低的地址,而返回地址0x0040052a 位于较高的地址。这里有什么问题?堆栈是否以相反的方向增长(从低到高地址)或堆栈帧的创建与上述顺序不同?请帮我理解。谢谢。
【问题讨论】:
-
在仅链接的答案中提到:wiki.cdot.senecacollege.ca/wiki/… 有一些关于 x86-64 如何不同的基础知识,例如使用 register-arg 调用约定。
标签: c assembly gcc x86-64 stack-memory