【发布时间】:2019-11-13 05:09:52
【问题描述】:
我正在查看x86-64 ABI 并对Figure 3.31 和Figure 3.32 中的示例有疑问:
int a, b;
long double ld;
double m, n;
__m256 u, y;
__m512 v, z;
extern void func (int a, double m, __m256 u, __m512 v, ...);
func (a, m, u, v, b, ld, y, z, n);
据说在将参数传递给func 函数时%rax 包含3,但我只能看到寄存器中传递了2 个浮点值:ld 和m。所以我实现了下面的例子:
impl.c:
#include <immintrin.h>
unsigned long func(int a, double m, __m256 u, __m512 v, ...){
unsigned long rax;
__asm__ __volatile__(
"" :
"=a" (rax) : :
);
return rax;
}
main.c
#include <immintrin.h>
#include <stdio.h>
unsigned long func(int a, double m, __m256 u, __m512 v, ...);
int main(void){
int a = 10,
b = 20;
long double ld = 30.0;
double m = 40.0,
n = 50.0;
__m256 u, y;
__m512 v, z;
printf("%lu\n", func(a, m, u, v, b, ld, y, z, n)); //prints 2
}
是错字吗?那么寄存器%rax的正确内容应该是2而不是3?
【问题讨论】:
-
你为什么不像普通人一样使用调试器,而不是希望 GCC 不会用你的 inline-asm hack 破坏传入的 RAX?或者用纯asm写函数。
-
@RaymondChen
n应该在堆栈上。 -
我认为图 3.32 完全是错误的。例如,没有提到
z,它说“只有命名的 __m256 和 __m512 参数可以在寄存器中传递”,然后它显示一个可变参数 __m256 正在寄存器中传递...... -
是的,当然可以。它可以在检查传入的 AL 和内联 asm 语句的代码之间生成它想要的任何代码。例如在禁用优化的情况下,它将设置一个堆栈帧并将固定的参数溢出到堆栈中。它可能不会修改 RAX,但通常不是一个安全的假设。使用调试器设置断点会容易得多,
asm("func: ret");在全局范围内也是如此。 -
糟糕,上面的链接错误,应该是github.com/hjl-tools/x86-psABI/blame/hjl/master/… line 2076