System V amd64 如何处理很长的返回值? [英] How does System V amd64 handle very long return values?

查看:71
本文介绍了System V amd64 如何处理很长的返回值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在简要研究用于 amd64/x86-64 架构的 System V ABI,并且很好奇它如何处理超过 128 位的返回值,其中 raxrdx还不够.

I'm briefly studying the System V ABI for amd64 / x86-64 architecture, and am curious how it handles return values over 128 bits, where rax and rdx aren't enough.

我在 Ubuntu 18.04 64 位(更一般地说,任何符合 amd64 POSIX 的系统)上编写了以下 C 代码:

I wrote the following C code on Ubuntu 18.04 64-bit (more generally, any amd64 POSIX-compliant system):

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 分配内存并分配初始值,然后返回它.

No surprise that the struct definition doesn't compile into any instructions, so the output only contains function bigfunc. The output assembly looks pretty straightforward, allocating memory from stack for struct big r and assign initial values, and returning it.

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

If I am understanding correctly, before ret is executed, register rax contains the value of rdi at the beginning of the function call (from QWORD PTR -40[rbp]). According to SysV, rdi is the first argument supplied to the function, which is impossible because the function accepts no arguments. So I have a few questions here:

  1. 当函数 bigfunc 没有参数时,rdi 是什么?
  2. 什么是rax(作为包含返回值的寄存器),当rdx在这个函数中没有被触及时?
  3. 函数如何返回这个 256 位 C 结构?
  1. What is rdi when the function bigfunc takes no arguments?
  2. What is rax (as the register that contains return value), when rdx is not touched in this function?
  3. How does the function return this 256-bit C structure?

推荐答案

根据 ABI (1),第 22 页

According to the ABI (1) ,page 22

如果类型有类 MEMORY,则调用者为返回提供空间value 并在 %rdi 中传递这个存储的地址,就好像它是第一个函数的参数.实际上,这个地址变成了一个隐藏的"第一个 ar-牙龈.此存储不得与被调用者可见的任何数据重叠除了这个参数之外的其他名称.返回时 %rax 将包含由%rdi

If the type has class MEMORY, then the caller provides space for the return value and passes the address of this storage in %rdi as if it were the first argument to the function. In effect, this address becomes a "hidden" first ar- gument. This storage must not overlap any data visible to the callee through other names than this argument. On return %rax will contain the address that has been passed in by the caller in %rdi

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

Page 17, 18 and 19 describes the classifications, I beliveve the following on page 19 is the clause designating your struct big as a MEMORY class.

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

(c) If the size of the aggregate exceeds two eightbytes and the first eight- byte isn’t SSE or any other eightbyte isn’t SSEUP, the whole argument is passed in memory.

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

i.e. the caller have to allocate memory for the return value, and pass a pointer to that memory in %rdi (and the called function returns that same address in %rax)

(1) https://github.com/hjl-tools/x86-psABI/wiki/X86-psABI ,尽管链接目前无法正常工作.

(1) there's newer offical versions of the ABI at https://github.com/hjl-tools/x86-psABI/wiki/X86-psABI , though the links arn't currently working properly.

这篇关于System V amd64 如何处理很长的返回值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆