我在 GCC 中有一个场景导致我出现问题。我得到的行为不是我期望的行为。总结一下情况,我提出了几个在硬件模拟器中实现的 x86-64 新指令。为了测试这些指令,我使用现有的 C 源代码并使用十六进制对新指令进行手工编码。因为这些指令与现有的 x86-64 寄存器交互,所以我使用输入/输出/clobber 列表来声明 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。
我正在使用 gcc 4.4.5。你认为可能会发生什么?我认为 GCC 将始终保存和恢复函数调用的寄存器。有什么办法可以强制执行吗?
谢谢!
编辑:顺便说一句,我正在编译这样的程序
gcc -static -m64 -mmmx -msse -msse2 -O0 test.c -o test