我在GCC中有一个场景给我带来了问题。我得到的行为不是我期望的行为。为了总结这种情况,我为x86-64提出了几个新的指令,这些指令是在硬件模拟器中实现的。为了测试这些指令,我正在使用现有的C源代码,并使用十六进制编码新指令。因为这些指令与现有的X8664寄存器进行交互,所以我使用输入/输出/ CulbBER列表来声明GCC的依赖关系。
如果我调用一个函数,比如printf,依赖寄存器就不会被保存和恢复。
例如

register unsigned long r9  asm ("r9")  = 101;
printf("foo %s\n", "bar");
asm volatile (".byte 0x00, 0x00, 0x00, 0x00" : /* no output */ : "q" (r9) );

101被分配给r9,内联程序集(在本例中是假的)依赖于r9。这在没有printf的情况下正确运行,但是当它存在时,GCC不会保存和恢复r9,并且在调用自定义指令时还有另一个值。
我想GCC可能已经秘密地改变了变量r9的赋值,但是当我这样做的时候
asm volatile (".byte %0" : /* no output */ : "q" (r9) );

看看程序集输出,它确实在使用%r9。
我使用的是GCC4.4.5。你认为会发生什么?我认为GCC总是在函数调用时保存和恢复寄存器。有什么办法可以强制执行吗?
谢谢!
编辑:顺便说一下,我正在这样编译程序
gcc -static -m64 -mmmx -msse -msse2 -O0 test.c -o test

最佳答案

ABI第3.2.1节规定:
寄存器%rbp、%rbx和%r12到%r15“属于”调用函数和
调用的函数是
必须保持他们的价值观。换句话说,被调用函数必须保留
这些寄存器为其调用方的值。剩余的寄存器“属于”被调用的
功能。如果调用函数希望在
函数调用时,它必须将值保存在其本地堆栈帧中。
所以您不应该期望除%rbp、%rbx和%r12到%r15之外的寄存器被函数调用保留。

07-24 09:44
查看更多