gpt4 book ai didi

c - System V中x86_64的C中浮点值的调用约定是什么?

转载 作者:太空宇宙 更新时间:2023-11-04 07:44:58 26 4
gpt4 key购买 nike

我目前正在深入到汇编领域,主要是从x86_64、C和System V AMD64的角度,通常以Linux为目标。
通过按顺序使用以下寄存器,整数(以及指针)值的调用约定非常简单:
RDI公司
相对强弱
黑索今
RCX公司
8兰特
R9号
XMM0-7型
较长的参数计数通过将值推送到子例程的堆栈帧上来处理。我得到了这些寄存器名。
对于更大的值(如结构和数组),约定似乎也要推入被调用方的堆栈帧。
但是,函数的浮点参数的调用约定是什么?是否使用浮点寄存器?
另一个相关的问题是:如果我有混合的参数类型呢?

void mixed(int a, float b, mystruct c) { /* ... */ }

如果我的函数采用这样的参数列表,如何从程序集调用这样的函数?在这样的交错arg列表中使用了哪些寄存器?

最佳答案

参数传递的调用约定在第3.2.3节的System V Application Binary Interface for AMD64PDF文档中指定。
我不确定文件是否可以在这里合法引用,但我至少可以解释一下。
分类类型
首先,文档定义了八种不同的参数值分类:
整数:使用通用寄存器的整数类型和指针
SSE:使用向量寄存器的类型。
SSEUP:与SSE类似,但主要用于存储大(>=128位)值的高位字节
X87:浮点类型。
X87UP:大型浮点类型的高位字节。
COMPLEX_X87:complex浮点类型的寄存器。
没有类:填充区域和空结构和联合,通常在堆栈的内存中。
内存:以独占方式在主内存堆栈上传递的类型。
分类规则
接下来定义了C类型如何适应这些分类:
_Boolcharshortintlonglong longfloat和指针被分类为整数,并将使用这些寄存器。
double_Decimal32_Decimal64__m64__float128被归类为SSE并将使用这些寄存器。
_Decimal128__m128__m256分成两半,在SSE中存储最低有效字节/位,在SSEUP中存储最高有效字节/位。
__m512被分成四个64位(8字节)值,其中最低有效字节存储为SSE,其余字节存储为SSEUP
long double类似地被分成64位(8字节)块,最低有效字节存储为SSE,其他所有字节存储为SSEUP
__int128值将其64位尾数存储为X87,16位指数填充到64位(8字节)并存储在X87以上。
long基本上是以整数形式存储为两个complex double值,前半部分是低位/字节,后半部分是高位/字节。可以将它们理解为一个结构:

typedef struct {
long low_bits, high_bits;
} __int128;

complex floatcomplex long double类型被分成两半,其中前一半是实组件,后一半是虚组件,并存储在SSE中。它们可以被理解为一个类似这样的结构:
typedef struct {
double real, imaginary;
} complex_double;

struct值被分类为复数。
unions、 structs和数组的逻辑相当复杂,有关详细信息,请参阅上面链接的文档。简而言之,有一个递归算法定义了如何传递聚合类型,决定如何传递值。
参数传递
现在我们有了处理 unions, %rdis和数组的分类系统和递归算法,我们将此系统和算法应用于函数的参数,每个参数包括以下步骤:
如果是内存对象,请将其写入堆栈。
如果是整数,请使用 %rsi%rdx%rcx%r8%r9%xmm0%xmm7中的下一个可用寄存器。
如果是SSE,则使用 %xmm 范围内的下一个可用寄存器。
如果是SSEUP,则使用上次使用的 寄存器的下一个可用64位块作为SSE类型。
如果它是X87、X87以上或复杂的X87,则它在内存中传递。
对所有参数值进行清洗和重复。如果给定类型的寄存器用完,请写入堆栈。
DR有一个由System V ABI定义的非平凡但相当简单的算法,用于传递不同类型的数据。

关于c - System V中x86_64的C中浮点值的调用约定是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57859857/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com