GCC与x64 sta

时间:2013-01-24 01:38:02

标签: function gcc assembly stack 64-bit

任何人都可以向我解释为什么跟随代码行 int main(int argc,char * argv [])

{
int i=17;
int output=0

.....

}

转换为以下x64汇编代码:

pushq %rbp
movq %rsp, %rbp
subq $32, %rsp
movl %edi, -20(%rbp)
movq %rsi,-32(%rbp)
movl $17, -8(%rbp)
movl $0, -4(%rbp)
...

我不知道为什么SP减少了32个。寄存器%edi,%rsi似乎对应于主代码中未使用的argc和* argv []。我认为[%esp,%rbp]之间的空间只分配给局部变量,而不是分配给函数args,因此上面代码中的大小应该只有8,即rsp应该减少8而不是32。有什么解释吗?

1 个答案:

答案 0 :(得分:0)

了解......部分会有所帮助。

我假设gcc决定...部分需要寄存器,因此它将变量压入堆栈。

堆栈可用于任何局部变量或函数参数。 SysV x64 ABI的唯一要求是前几个函数参数从寄存器开始。

然后,函数可以将参数移动到堆栈中,如果需要,可以将局部变量放入寄存器中,这取决于编译器!

不保证本地变量可以放在堆栈中! args也不会留在寄存器中。

所以它推动了argc和argv,然后决定推送i并输出。那是24个字节的空间。但是如果接下来是一个函数调用,那么堆栈必须对齐到16个字节,因此它会变为32。

尝试-O3并查看代码是否有问题。

换句话说:

Args是这样的: %RDI RSI% %的RDX %RCX %RBX R8% %R9 (堆栈上的额外args) (红区)

是功能的开始。然后,该函数可以对堆栈执行任何操作。是的,无论如何!只要它在状态下返回堆栈就可以了。

(注意,这是针对系统V(除了窗口以外的所有内容使用),窗口不同)