被调用方如何知道参数是通过寄存器而不是堆栈传递的

How does callee know arguments are passed through registers instead of stack

本文关键字:堆栈 寄存器 方如何 调用 参数      更新时间:2023-10-16

假设我们得到一个简单的程序

#include <cstdio>
int main(int argc, char* argv[]) {
    int n = argc;
    if (n > 1) {
        n = 1;
    }else {
        n = -1;
    }
    printf("%dn", n);
    return 0;
}

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

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包含预期的参数?更一般地说,它如何知道使用了哪些寄存器?

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