System V amd64如何处理非常长的返回值?

时间:2019-01-03 13:08:44

标签: assembly posix return-value x86-64 abi

我正在简要研究amd64 / x86-64体系结构的System V ABI,并很好奇它如何处理128位以上的返回值,而其中raxrdx还不够。 / p>

我在Ubuntu 18.04 64位(更常见的是,任何与amd64 POSIX兼容的系统)上编写了以下C代码:

struct big {
    long long a, b, c, d;
};

struct big bigfunc(void) {
    struct big r = {12, 34, 56, 78};
    return r;
}

将其编译为gcc -S -masm=intel t.c,并检查了t.s

        .file   "t.c"
        .intel_syntax noprefix
        .text
        .globl  bigfunc
        .type   bigfunc, @function
bigfunc:
.LFB0:
        .cfi_startproc
        mov     QWORD PTR -40[rsp], rdi
        mov     QWORD PTR -32[rsp], 12
        mov     QWORD PTR -24[rsp], 34
        mov     QWORD PTR -16[rsp], 56
        mov     QWORD PTR -8[rsp], 78
        mov     rcx, QWORD PTR -40[rsp]
        mov     rax, QWORD PTR -32[rsp]
        mov     rdx, QWORD PTR -24[rsp]
        mov     QWORD PTR [rcx], rax
        mov     QWORD PTR 8[rcx], rdx
        mov     rax, QWORD PTR -16[rsp]
        mov     rdx, QWORD PTR -8[rsp]
        mov     QWORD PTR 16[rcx], rax
        mov     QWORD PTR 24[rcx], rdx
        mov     rax, QWORD PTR -40[rsp]
        ret
        .cfi_endproc
.LFE0:
        .size   bigfunc, .-bigfunc
        .ident  "GCC: (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0"
        .section        .note.GNU-stack,"",@progbits

结构定义不会编译为任何指令不足为奇,因此输出仅包含函数bigfunc。输出程序集看起来非常简单,它从堆栈中为struct big r分配内存,并分配初始值,然后将其返回。

如果我正确理解,在执行ret之前,寄存器rax在函数调用开始时(从rdi开始包含QWORD PTR -40[rbp]的值。根据SysV,rdi是提供给该函数的第一个参数,这是不可能的,因为该函数不接受任何参数。所以我在这里有几个问题:

  1. 当函数rdi不带参数时,bigfunc是什么?
  2. 当此功能中未触及rax时,rdx是什么(作为包含返回值的寄存器)?
  3. 函数如何返回此256位C结构?

1 个答案:

答案 0 :(得分:1)

根据ABI(1),第22页

  

如果类型具有MEMORY类,则调用方为返回提供空间    值,并以%rdi的形式传递此存储的地址,就像它是第一个    该函数的参数。实际上,该地址成为“隐藏”的第一个Ar-    胶质的。此存储空间不得与被调用方通过以下方式可见的任何数据重叠    除此参数外的其他名称。    返回时,%rax将包含由    %rdi

中的呼叫者

第17、18和19页描述了分类,我相信 第19页的以下内容是将struct big指定为MEMORY类的子句。

  

(c)如果聚合的大小超过两个八字节,则第一个   整个八字节不是SSE或其他八字节不是SSEUP   参数在内存中传递。

即调用者必须为返回值分配内存,并在%rdi中传递一个指向该内存的指针(被调用的函数在%rax中返回相同的地址)

(1)在https://github.com/hjl-tools/x86-psABI/wiki/X86-psABI上有更新的ABI官方版本,尽管这些链接当前无法正常工作。