c - 汇编错误: "operand type mismatch for ` rol'"with multiple input operands

标签 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_tint32_t 来表示 i,它没有改变任何东西。

我必须说,在这个环境中,我对 C 中的嵌入式 asm 还很陌生,我只在 Windows 上使用 Visual Studio 完成了一些基本的内联汇编。

最佳答案

正如 Michael Petch 在评论中所说,

the only register that is allowed for a shifting instruction that controls the number of bits to shift is 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"
    );
}

The c says to use the CL register (assuming you change the type of variable i to int8_t instead of int16_t. . The Capital-Eye (I) says the constraint can also be an immediate value between 0 and 32.

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

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

(...) machine constraints can be found here: gcc.gnu.org/onlinedocs/gcc/… under the i386 info

There's no reason to use inline asm for rotates. Best practices for circular shift (rotate) operations in C++

When debugging inline asm, you should look at the compiler-generated asm to see what it substituted into the template. e.g. godbolt.org is handy: How to remove "noise" from GCC/clang assembly output?. You can even do stuff like nop # %0 %1 %2 to just see what the compiler picked for all the operands, whether you reference them in the template or not. See also stackoverflow.com/tags/inline-assembly/info for more guides and examples.

关于c - 汇编错误: "operand type mismatch for ` rol'"with multiple input operands,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53137123/

相关文章:

创建 TCP 服务器来托管 ELF 文件

c - 海湾合作委员会 4.8.1 : combining c code with c++11 code

c++ - 如何将应用程序与静态库链接+为什么这不起作用

linux - 为什么这里的 Solaris 汇编器生成的机器码与 GNU 汇编器不同?

assembly - PIC16F887 Timer0计数溢出

c - 如何获取我的代码的结束地址

java - 为什么我收到警告(453) Cant apply (char *STRING, int LENGTH) no typemaps are Defined

c - scanf Cppcheck 警告

c - 当我进行UDP广播后,我如何知道我在哪个端口上广播?

c++ - 如何摆脱内部编译器错误 : Illegal instruction min() _GLIBCXX_USE_NOEXCEPT { return __FLT_MIN__; }