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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 00:05:51  来源:igfitidea点击:

C to assembly call convention 32bit vs 64bit

clinuxassemblyx86x86-64

提问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 %ebxand 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 %espand %epbneeds to be replaced with %rspand %rpb, but digging with GDB reveals that the arguments are nowhere to be found on the stack!

然而,当我在 64 位机器上编译它时,我得到了一些非常意外的结果。我修改了显而易见的事实,比如%espand%epb需要替换为%rspand %rpb,但是使用 GDB 挖掘发现在堆栈中找不到参数!

Checking out what happens by using the -Soption to GCC I can see that instead of pushing the variables on the stack, GCC stores the arguments in registers.

通过使用-SGCC 选项检查会发生什么,我可以看到 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++ 编译器可以像汇编参考一样使用。