Linux C 到汇编调用约定 32 位与 64 位
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4265970/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C to assembly call convention 32bit vs 64bit
提问by Cbsch
I have been following the excellent book Programming Ground Up, wanting to learn assembly. Although not in the book at this point, I wanted to call my assembly function from C. on a 32 bit machine, this works as is when working from the book.
我一直在关注《Programming Ground Up》这本书,想学习汇编。虽然此时不在本书中,但我想在 32 位机器上从 C. 调用我的汇编函数,这与本书中的工作一样有效。
What I do here is storing the first argument in %ebx
and the second in %ecx
.
我在这里做的是将第一个参数存储%ebx
在%ecx
.
.type power, @function
.globl power
power:
pushq %ebp
movl %esp, %ebp
subl , %esp
movl 8(%ebp), %ebx
movl 12(%ebp), %ecx
I compile this (and the rest of the function) into an object file, create a main.c, where I prototype the function and call it, something like this:
我将这个(以及函数的其余部分)编译成一个目标文件,创建一个 main.c,在那里我对函数进行原型设计并调用它,如下所示:
int power(int b, int x);
int a = power(2, 1);
However, when I compile this on a 64 bit machine, I get some very unexpected results. I modified the obvious, like the fact that %esp
and %epb
needs to be replaced with %rsp
and %rpb
, but digging with GDB reveals that the arguments are nowhere to be found on the stack!
然而,当我在 64 位机器上编译它时,我得到了一些非常意外的结果。我修改了显而易见的事实,比如%esp
and%epb
需要替换为%rsp
and %rpb
,但是使用 GDB 挖掘发现在堆栈中找不到参数!
Checking out what happens by using the -S
option to GCC I can see that instead of pushing the variables on the stack, GCC stores the arguments in registers.
通过使用-S
GCC 选项检查会发生什么,我可以看到 GCC 将参数存储在寄存器中,而不是将变量压入堆栈。
movl , %esi
movl , %edi
call power
On the 32 bit machine, it does what I expect and push the arguments on the stack:
在 32 位机器上,它执行我期望的操作并将参数推送到堆栈上:
movl , 4(%esp)
movl , (%esp)
call power
Now what is going on here? Why does GCC pass the arguments in registers on 64 bit and on the stack on 32 bit? This is very confusing! And I can't find any mention on this anywhere. Is there anyone who can enlighten me on this situation?
现在这里发生了什么?为什么 GCC 在 64 位的寄存器和 32 位的堆栈中传递参数?这非常令人困惑!我在任何地方都找不到任何提及。有没有人可以在这种情况下启发我?
采纳答案by Alex F
64-bit C calling convention is: %rdi, %rsi, %rdx, %rcx, %r8 and %r9
64 位 C 调用约定是:%rdi、%rsi、%rdx、%rcx、%r8 和 %r9
See full description here: "System V Application Binary Interface: AMD64 Architecture Processor Supplement" http://www.x86-64.org/documentation/abi.pdf
请参阅此处的完整说明: “System V 应用程序二进制接口:AMD64 架构处理器补充”http://www.x86-64.org/documentation/abi.pdf
3.2 Function Calling Sequence
3.2 函数调用顺序
When I learned the same topic, I made small C programs with required functions, compiled them in 64 bit compiler and read the Assembly code produced by C compiler. C/C++ compiler can be used like kind of Assembly reference.
当我学习同一主题时,我制作了带有所需功能的小 C 程序,在 64 位编译器中编译它们并阅读 C 编译器生成的汇编代码。C/C++ 编译器可以像汇编参考一样使用。