该值用于ABI文档中所述的优化
开场白应该用
%rax
以避免不必要地保存XMM寄存器这对于防止XMM单元初始化的纯整数程序尤其重要。
https://software.intel.com/sites/default/files/article/402129/mpx-linux64-abi.pdf
当你打电话
va_start
它将把寄存器中传递的所有参数保存到
注册保存区域
首先,任何已知要使用的函数
虚拟开始
在函数开始时,需要将可能用于将参数传递到堆栈的所有寄存器保存到寄存器保存区域中,以便将来通过
虚拟开始
和
va_arg
. 这是一个明显的步骤,我相信在任何平台上都是非常标准的,有一个寄存器调用约定寄存器保存为整数寄存器,后跟浮点寄存器。。。
但是保存所有8个向量寄存器可能会很慢,所以编译器可以选择使用传入的值来优化它
al
... 作为优化,在函数调用期间,
%拉克斯
需要保留用于保存参数的SSE寄存器的数量,以允许varargs调用方在没有浮点参数的情况下完全避免接触FPU。
https://blog.nelhage.com/2010/10/amd64-and-va_arg/
既然你想拯救
至少
使用的寄存器,该值可以大于实际使用的寄存器数所以ABI里有这条线
的内容
%al
不需要精确匹配寄存器的数量,但必须是所用向量寄存器数量的上限,并且在0–8范围内。
你可以从
prolog of ICC
sub rsp, 216 #5.1
mov QWORD PTR [8+rsp], rsi #5.1
mov QWORD PTR [16+rsp], rdx #5.1
mov QWORD PTR [24+rsp], rcx #5.1
mov QWORD PTR [32+rsp], r8 #5.1
mov QWORD PTR [40+rsp], r9 #5.1
movzx r11d, al #5.1
lea rax, QWORD PTR [r11*4] #5.1
lea r11, QWORD PTR ..___tag_value_varstrings(int, ...).6[rip] #5.1
sub r11, rax #5.1
lea rax, QWORD PTR [175+rsp] #5.1
jmp r11 #5.1
movaps XMMWORD PTR [-15+rax], xmm7 #5.1
movaps XMMWORD PTR [-31+rax], xmm6 #5.1
movaps XMMWORD PTR [-47+rax], xmm5 #5.1
movaps XMMWORD PTR [-63+rax], xmm4 #5.1
movaps XMMWORD PTR [-79+rax], xmm3 #5.1
movaps XMMWORD PTR [-95+rax], xmm2 #5.1
movaps XMMWORD PTR [-111+rax], xmm1 #5.1
movaps XMMWORD PTR [-127+rax], xmm0 #5.1
..___tag_value_varstrings(int, ...).6:
本质上是
Duff's device
. 这个
r11
寄存器在xmm保存指令之后加载地址,然后
al*4
从结果中减去
movaps XMMWORD PTR [rax-X], xmmX
是4字节长)以跳到
movaps
我们应该运行的指令
如我所见,其他编译器总是保存所有的向量寄存器,或者根本不保存它们,所以它们不关心
艾尔
的值,然后检查它是否为零
通用寄存器总是被保存,可能是因为将6个寄存器移到内存中而不是花时间进行条件检查、地址计算和跳转比较便宜因此,您不需要一个参数来确定在寄存器中传递了多少个整数
这是一个
similar question to yours
. 您可以在下面的链接中找到更多信息