我有一些C代码,当提供给Compiler Explorer时,它输出:
mov BYTE PTR [rbp-4], al
mov eax, ecx
mov BYTE PTR [rbp-8], al
mov eax, edx
mov BYTE PTR [rbp-12], al
但是,如果我使用GCC或G ++,它就会给我这个:
mov BYTE PTR 16[rbp], al
mov eax, edx
mov BYTE PTR 24[rbp], al
mov eax, ecx
mov BYTE PTR 32[rbp], al
我不知道为什么BYTE PTR不同。他们的地址完全错误,我不知道为什么他们在[rdp]部分之前。
如果您知道如何使用gcc或g ++复制第一个输出,请帮助!
gcc.exe(GCC)8.2.0
类似于Windows x64调用约定的GCC,正在使用其调用方保留的影子空间(返回地址上方32字节)。 Godbolt的GCC安装了目标GNU / Linux,即x86-64 System V ABI。
您可以使用__attribute__((ms_abi))
标记功能,从而在Godbolt上获得相同的代码。当然,这意味着您的调用者必须在原型中看到该属性,以便它知道保留该空间以及将函数args传入的寄存器。
Windows x64调用约定通常比x86-64 System V差;例如,较少的arg传递寄存器。它的唯一优点之一是可变参数函数的实现更容易(由于阴影空间),并且具有一些保留呼叫的XMM规则。 (可能太多,但是x86-64 SysV的值为零。)因此,您更有可能希望在Windows上使用交叉编译器(针对GNU / Linux),或在所有函数上使用__attribute__((sysv_abi))
。 (https://gcc.gnu.org/onlinedocs/gcc/x86-Function-Attributes.html)
调用约定的XMM部分通常与内核代码无关;大多数内核通过不让编译器使用SIMD / FP指令来避免在内核进入/退出时保存/恢复SIMD / FPU状态。