assembly - GCC 内联汇编器,混合寄存器大小 (x86)

标签 assembly gcc x86 inline-assembly cpu-registers

有谁知道如何消除以下汇编器警告?

代码为 x86,32 位:

int test (int x)
{
  int y;
  // do a bit-rotate by 8 on the lower word. leave upper word intact.
  asm ("rorw $8, %0\n\t": "=q"(y) :"0"(x));
  return y;
}

如果我编译它,我会收到以下(非常有效)警告:

Warning: using `%ax' instead of `%eax' due to `w' suffix

我正在寻找一种方法来告诉编译器/汇编器我想要访问 %0 的低 16 位子寄存器。访问字节子寄存器(在本例中为 AL 和 AH)也很高兴知道。

我已经选择了“q”修饰符,因此编译器被迫使用 EAX、EBX、ECX 或 EDX。我已经确保编译器必须选择一个具有子寄存器的寄存器。

我知道我可以强制 asm 代码使用特定的寄存器(及其子寄存器),但我想将寄存器分配工作留给编译器。

最佳答案

如果我没记错的话,你可以使用%w0。我刚刚也测试过。 :-)

int
test(int x)
{
    int y;
    asm ("rorw $8, %w0" : "=q" (y) : "0" (x));
    return y;
}

编辑:响应OP,是的,您也可以执行以下操作:

int
test(int x)
{
    int y;
    asm ("xchg %b0, %h0" : "=Q" (y) : "0" (x));
    return y;
}

对于 x86,它记录在 x86 Operand Modifiers section 中手册的扩展汇编部分。

对于非 x86 指令集,您可能需要深入研究 GCC 源代码中的 .md 文件。例如,在正式记录之前,gcc/config/i386/i386.md 是唯一可以找到它的地方。

(相关:In GNU C inline asm, what are the size-override modifiers for xmm/ymm/zmm for a single operand? 用于向量寄存器。)

关于assembly - GCC 内联汇编器,混合寄存器大小 (x86),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/118730/

相关文章:

assembly - EDX和DX是同一个寄存器吗?

c++ - 程序集:C++ 堆栈变量地址不同/错误?

assembly - 对多个位进行高效的 assembly 检查

c - char * 的大小是否与 int * 的大小相同?

linux x86 汇编语言 sys_read 调用的第一个参数应该为 0 (stdin)

c - 避免 gcc 函数序言开销?

c++ - gcc 编译器标志以抑制编译期间模板错误的模板扩展?

optimization - 如何消除汇编程序可执行文件的膨胀?

gcc - 裸机工具链有何特别之处?

linux - 在什么情况下控制权从用户空间传递到 Linux 内核空间?