我正在对在 64 位 Linux 上运行的 gnu C 代码进行一些扩展的汇编优化。我想从汇编代码中打印调试消息,这就是我遇到以下内容的方式。我希望有人能解释我在这种情况下应该做什么。
看看这个示例函数:
void test(int a, int b, int c, int d){
__asm__ volatile (
"movq $0, %%rax\n\t"
"pushq %%rax\n\t"
"popq %%rax\n\t"
:
:"m" (a)
:"cc", "%rax"
);
}
由于函数的四个参数属于 INTEGER 类,它们将通过寄存器传递,然后压入堆栈。对我来说奇怪的是 gcc 实际上是如何做到的:
test:
pushq %rbp
movq %rsp, %rbp
movl %edi, -4(%rbp)
movl %esi, -8(%rbp)
movl %edx, -12(%rbp)
movl %ecx, -16(%rbp)
movq $0, %rax
pushq %rax
popq %rax
popq %rbp
ret
传递的参数被压入堆栈,但堆栈指针没有减少。因此,当我执行 pushq %rax
时,a
和 b
的值将被覆盖。
我想知道的是:有没有办法让 gcc 正确设置本地堆栈?难道我不应该在函数调用中使用 push
和 pop
吗?
最佳答案
x86-64 abi 在堆栈指针下提供了一个 128 字节的红色区域,编译器决定使用它。您可以使用 -mno-red-zone
选项将其关闭。
关于c - 根据 linux 上的 x86-64 调用约定设置本地堆栈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27361534/