【问题标题】:Error with gcc inline assemblygcc 内联汇编出错
【发布时间】:2014-10-12 20:11:18
【问题描述】:

我正在尝试学习如何编写 gcc 内联汇编。

下面的代码应该执行shl指令并返回结果。

#include <stdio.h>
#include <inttypes.h>

uint64_t rotate(uint64_t x, int b)
{
    int left = x;
    __asm__ ("shl %1, %0"
             :"=r"(left)
             :"i"(b), "0"(left));

   return left;
}

int main()
{
    uint64_t a = 1000000000;
    uint64_t res = rotate(a, 10);
    printf("%llu\n", res);
    return 0;
}

编译失败,error: impossible constraint in asm

问题基本上出在"i"(b)。我已经尝试过"o""n""m" 等,但它仍然不起作用。要么是这个错误,要么是operand size mismatch

我做错了什么?

【问题讨论】:

    标签: c gcc assembly x86 x86-64


    【解决方案1】:

    正如所写,您的代码为我正确编译(我已启用优化)。但是,我相信您可能会发现这会更好一些:

    #include <stdio.h>
    #include <inttypes.h>
    
    uint64_t rotate(uint64_t x, int b)
    {
        __asm__ ("shl %b[shift], %[value]"
                 : [value] "+r"(x)
                 : [shift] "Jc"(b)
                 : "cc");
    
       return x;
    }
    
    int main(int argc, char *argv[])
    {
        uint64_t a = 1000000000;
        uint64_t res = rotate(a, 10);
        printf("%llu\n", res);
        return 0;
    }
    

    请注意,“J”代表 64 位。如果您使用的是 32 位,则“I”是正确的值。

    其他注意事项:

    • 您要将旋转值从 uint64_t 截断为 int?您是否正在编译 32 位代码?我不相信 shl 在编译为 32 位时可以进行 64 位旋转。
    • 在输入约束上允许“c”意味着您可以使用可变旋转量(即在编译时不进行硬编码)。
    • 由于shl修改了flags,所以使用“cc”让编译器知道。
    • 使用 [name] 形式使汇编更易于阅读 (IMO)。
    • %b 是一个修饰符。见https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#i386Operandmodifiers

    如果您想真正了解内联 asm,请查看最新的 gcc 文档:https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-20
      • 1970-01-01
      • 2011-03-08
      • 1970-01-01
      • 1970-01-01
      • 2011-05-27
      • 1970-01-01
      • 2011-04-23
      相关资源
      最近更新 更多