x86_64函数传参规范

  1. 前6个参数使用寄存器传递 (%rdi, %rsi, %rdx, %rcx, %r8, %r9)
  2. 第7个开始往后用栈传递,后面的参数先压栈(高地址),左边的参数后压栈(低地址)
  3. %rax作为返回值使用

举例来说:

$ cat test.c
void foo(long p1, long p2, long p3, long p4, long p5, long p6, long p7, long p8, long p9) {
}
void callee(long p1, long p2, long p3, long p4, long p5, long p6, long p7, long p8, long p9) {
    foo(p1, p2, p3, p4, p5, p6, p7, p8, p9);
}
void caller() {
    callee(1L,2L,3L,4L,5L,6L,7L,8L,9L);
}
image.png

$ gcc -S -O0 test.c

看汇编码:

     1  caller:
     2      pushq   %rbp
     3      movq    %rsp, %rbp
     4      subq    $24, %rsp       // 为第7,8,9这三个参数分配栈空间
     5      movq    $9, 16(%rsp)    // 压入第9个参数,后面的参数在高地址
     6      movq    $8, 8(%rsp)     // 压入第8个参数
     7      movq    $7, (%rsp)      // 压入第7个参数
     8      movl    $6, %r9d        // 第6个参数,寄存器%r9
     9      movl    $5, %r8d        // 第5个参数,寄存器%r8d
    10      movl    $4, %ecx        // 第4个参数,寄存器%rcx
    11      movl    $3, %edx        // 第3个参数,寄存器%rdx
    12      movl    $2, %esi        // 第2个参数,寄存器%rsi
    13      movl    $1, %edi        // 第1个参数,寄存器%rdi
    14      call    callee
    15      leave
    16      ret

看callee:

     1  callee:
     2      pushq   %rbp
     3      movq    %rsp, %rbp
     4      subq    $72, %rsp            -- 为所有参数准备本地空间 9 * 8 = 72
     5      movq    %rdi, -8(%rbp)       -- 第1个参数,存入高地址
     6      movq    %rsi, -16(%rbp)      -- 第2个参数,存入
     7      movq    %rdx, -24(%rbp)      -- 第3个参数,存入
     8      movq    %rcx, -32(%rbp)      -- 第4个参数,存入
     9      movq    %r8, -40(%rbp)       -- 第5个参数,存入
    10      movq    %r9, -48(%rbp)       -- 第6个参数,存入,前面6个参数都是通过寄存器传递的
                                      -- 下面开始为调用foo准备参数
    11      movq    -48(%rbp), %r9       -- 准备第6个参数,入%r9
    12      movq    -40(%rbp), %r8       -- 准备第5个参数,入%r8
    13      movq    -32(%rbp), %rcx      -- 准备第4个参数,入%rcx
    14      movq    -24(%rbp), %rdx      -- 准备第3个参数,入%rdx
    15      movq    -16(%rbp), %rsi      -- 准备第2个参数,入%rsi
    16      movq    -8(%rbp), %rax       -- 准备第1个参数,入%rax,注意这里是%rax是临时寄存器,最后会存入%rdi
    17      movq    32(%rbp), %rdi       -- 下面两行,准备第9个参数,存入栈16(%rsp)
    18      movq    %rdi, 16(%rsp)
    19      movq    24(%rbp), %rdi       -- 下面两行,准备第8个参数,存入栈8(%rsp)
    20      movq    %rdi, 8(%rsp)
    21      movq    16(%rbp), %rdi       -- 下面两行,准备第7个参数,存入栈0(%rsp)
    22      movq    %rdi, (%rsp)
    23      movq    %rax, %rdi           -- 把16行准备好的第一个参数,存入最终寄存器%rdi
    24      call    foo
    25      leave
    26      ret
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容