【问题标题】:How does callee know arguments are passed through registers instead of stack [duplicate]被调用者如何知道参数是通过寄存器而不是堆栈传递的
【发布时间】:2018-04-15 15:52:08
【问题描述】:

假设我们有一个简单的程序

#include <cstdio>

int main(int argc, char* argv[]) {
    int n = argc;
    if (n > 1) {
        n = 1;
    }else {
        n = -1;
    }
    printf("%d\n", n);
    return 0;
}

以及在ubuntu x64(Windows子系统)下使用g++ main.cpp -S -O1生成的汇编代码sn-p

subq    $8, %rsp
cmpl    $1, %edi
setg    %dl
movzbl  %dl, %edx
leal    -1(%rdx,%rdx), %edx
movl    $.LC0, %esi
movl    $1, %edi
movl    $0, %eax
call    __printf_chk
movl    $0, %eax
addq    $8, %rsp
ret

既没有push,也没有任何访问和写入内存的指令。所以参数n 必须通过%edx。现在我想知道 c 库函数 __printf_chk 是如何知道 %edx 包含预期参数的?更一般地说,它如何知道使用了哪些寄存器?

【问题讨论】:

标签: c++ assembly g++ x86-64 calling-convention


【解决方案1】:

这是由平台的 ABI(应用程序二进制接口)指定的。编译器已编译 __printf_chk 以遵循您的平台 ABI(在本例中为 amd64 SysV ABI),导致它期望参数位于某些位置。如需进一步阅读,请查看此 ABI 文档。

【讨论】:

    猜你喜欢
    • 2020-08-25
    • 2016-03-15
    • 2010-11-01
    • 1970-01-01
    • 2018-01-14
    • 1970-01-01
    • 2015-04-20
    • 2014-10-15
    • 1970-01-01
    相关资源
    最近更新 更多