asm错误:具有多个输入操作数的“操作符类型与'rol'不匹配”

时间:2018-11-04 01:57:24

标签: c gcc assembly operands

环境:Debian 9.5-gcc 6.3.0

当我尝试使用多个InputOperands时,无法使用嵌入式程序集功能。

我正在使用以下代码(基本rol函数,1 InputOperand,预定义rol操作数):

#include <stdio.h>
#include <stdlib.h>

void asm_rol(int32_t* p_rolled)
{
    __asm__ volatile
    (
        ".intel_syntax noprefix;"
        "rol %0, 1;"
        :"=a"(*p_rolled)
        :"a"(*p_rolled)
        :"cc"
    );
}

int main(int argc, char** argv)
{
    int32_t test = 0x1;
    asm_rol(&test);

    printf("0x%08x\n", test);
    return 0;
}

这将打印0x00000002,并且是rol 0x1, 1的正确结果。

现在,我不明白为什么以下代码无法编译。我认为我对InputOperands的使用是不好的:

#include <stdio.h>
#include <stdlib.h>

void asm_rol(int32_t* p_rolled, int16_t i)
{
    __asm__ volatile
    (
        ".intel_syntax noprefix;"
        "rol %0, %1;"
        :"=a"(*p_rolled)
        :"a"(*p_rolled), "b"(i)
        :"cc"
    );
}

int main(int argc, char** argv)
{
    int32_t test = 0x1;
    asm_rol(&test, 1);

    printf("0x%08x\n", test);
    return 0;
}

gcc返回错误:

resolve.c: Assembler messages:
resolve.c:6: Error: operand type mismatch for `rol'

我尝试将int8_t的{​​{1}}和int32_t用于i,它没有任何改变。

我必须说,在这种环境下,我是C嵌入式AS的新手,我只使用Windows上的Visual Studio完成了一些基本的内联汇编。

1 个答案:

答案 0 :(得分:3)

如Michael Petch在评论中所说,

  

控制移位位数的移位指令唯一允许的寄存器是CL

他还提供了以下解决方案:

void asm_rol(int32_t* p_rolled, int8_t i) {
    __asm__ volatile
    (
        ".intel_syntax noprefix;"
        "rol %0, %1;"
        :"+a"(*p_rolled)
        :"cI"(i) :"cc"
    );
}
     

c表示要使用CL寄存器(假设您将变量i的类型更改为int8_t而不是int16_t。Capital-Eye(I)说约束也可以是0到32之间的立即值。

正如Michael Petch和Peter Cordes在评论中指出的那样,我的代码无法正常工作,因为我使用%1作为rol操作数,但是正确的变量是%2。我犯了这个错误,是因为我认为InputOperands仅引用了%#

Michael Petch和Peter Cordes还提供了一些不错的文档:

  

(...)机器约束可以在这里找到:i386信息下的gcc.gnu.org/onlinedocs/gcc/…

     

没有理由使用内联汇编进行旋转。 Best practices for circular shift (rotate) operations in C++

     

调试嵌入式asm时,应查看由编译器生成的asm,以查看将其替换为模板的内容。例如godbolt.org很方便:How to remove "noise" from GCC/clang assembly output?。您甚至可以执行诸如nop#%0%1%2之类的操作,以查看编译器为所有操作数选择的内容,无论是否在模板中引用它们。另请参见stackoverflow.com/tags/inline-assembly/info,以获取更多指南和示例。