使用 gcc 编译内联汇编时出错,“shl”

Posted

技术标签:

【中文标题】使用 gcc 编译内联汇编时出错,“shl”【英文标题】:error compiling inline assembly with gcc, "shl" 【发布时间】:2013-01-04 16:53:05 【问题描述】:

这是我试图转换为 gcc 风格的 asm 内联汇编代码的实际代码。

#include<iostream>
using namespace std;

int reverse(int num);

int main()
    int num;
    cout << "enter number: ";
    cin >> num;
    cout << endl;
    cout << reverse(num);
    return 0;


int reverse(int num)
    if(num == 0 || num == 1)
        return num;
    
    __asm
    
        xor eax, eax
        xor ecx, ecx     
        mov ebx, num    
        clc             ; clear carry
not_found:
        inc ecx
        shl ebx, 1
        jnc not_found


        rcr eax, 1
        mov edx, ecx
again:
        shl ebx, 1
        rcr eax, 1
        inc ecx
        cmp ecx, 32
        jne again

        dec edx     
again2:     
        shr eax, 1
        dec edx
        cmp edx, 0
        jne again2
    


由于我无法使用 gcc 编译上述代码,我尝试将其转换为可以由 gcc 编译器成功编译的东西,但到目前为止我无法产生任何有意义的结果。

【问题讨论】:

你能提供更多关于这个 sn-p 的上下文(temp,num 的声明)。它对我来说编译得很好。 不是汇编向导,但我在shll 中看到两个l,这可能意味着这是long int 版本,num 的类型是什么确切 ? 也提供您的架构可能会有所帮助。 是的,它对我来说也可以编译 32 位和 64 位。当然这是对内联汇编的可怕滥用,我当然希望最终它会成为更有意义的代码。另请注意clc 没有效果,因为shl 不读取进位。 @Jester, Bo:你太不仁慈了。我假设这是一个代码 sn-p。 【参考方案1】:

根据OP注释中的代码,这里是一个使用内联汇编移位一位的修改示例:

#include<iostream>
using namespace std;
int reverse(int num);
int main()

    int num;
    cout << "enter number: ";
    cin >> num;
    cout << endl;
    cout << reverse(num) << endl;
    return 0;


int reverse(int num)

    if (num == 0 || num == 1)
    
        return num;
    
    int temp = 0;
    asm( "shll $1, %0 \n\t" : "=r"(temp) : "0"(num));
    return temp;

请注意,如果您使用r 约束要求gcc 将操作数放入寄存器中,因此真的没有理由自己mov 它们(至少在这个小示例中)。 另外,我在输入约束中使用了0 来表示它应该是与输出相同的寄存器,因为shl 就是这样工作的。

仍然不确定num == 1这个条件,但大概是因为我们不知道完整函数的实际作用。

【讨论】:

以上是关于使用 gcc 编译内联汇编时出错,“shl”的主要内容,如果未能解决你的问题,请参考以下文章

扩展内联汇编 gcc - 计算二次公式根

GCC 内联汇编中的标签

gcc 内联汇编行为异常

LLVM GCC 4.2 中内联汇编的奇怪编译

GCC 内联汇编错误:表达式后出现垃圾 `(%ebp)+4'

转贴GCC内联汇编基础