Eclipse C ++:如何插入内联汇编代码?

时间:2014-12-23 14:09:52

标签: assembly x86 g++ inline-assembly

我有一个C ++项目,我想在程序集中插入代码块。 我可以使用哪些解决方案? 我使用g ++和我的cpu的编译器是i5。

到目前为止,我试过了:

void f1(int a){
    asm(
        "mov edx,4"
    );
}
............

编译时我收到此错误:

error: unknown use of instruction mnemonic without a size suffix

我尝试了更多我在谷歌上发现的例子,但每个例子都给我一个不同的错误。

EDIT2:

void f1(int a) {
    int r = 0;
    cout << "start";
    __asm__(
            "movl %edx,4;"
    );
    cout << r;
    cout << a;
    cout << "end";
}

int main(){
    f1(2);
    return 1;
}

成功构建但输出为空...不打印任何内容......但是如果删除__asm_(..),则输出如下:&#34; start02end&#34; ..为什么用asm块不打印什么?

1 个答案:

答案 0 :(得分:1)

gcc内联汇编是一件复杂的事情。有关详细信息,请阅读documentation。即使它似乎有效,它也可能在不同情况下神秘地失败。你真的需要知道你在做什么。

也就是说,这是一个快速概述:gcc根本不解析你的asm块,它认为它是一个黑盒子。您需要根据它所期望的输入,它提供的输出以及它所破坏的状态来描述它。

将4加载到edx的示例毫无意义,您只是在不知道编译器使用了什么寄存器的情况下覆盖寄存器。您不能指望该代码的任何特定结果。此外,您的at&amp; t翻译(movl %edx, 4)是错误的,因为at&t; T期望操作数的顺序相反,并且immediates需要$前缀。因此,您的代码会将edx的内容写入内存位置4,这将会出现段错误。

有效(但仍无意义)的例子是:

__asm__("movl $4, %%edx" : : : "edx");

这会将4加载到edx,同时还会告诉编译器您已销毁之前的edx值。该指令将包含在结果程序中,但由于未使用edx并且asm块没有输出,因此它将无效。

在您的示例中插入了一个更有趣的示例:

void f1(int a) {
    int r = 0;
    cout << "start";
    __asm__("addl $1, %0" : "+d" (a));
    cout << r;
    cout << a;
    cout << "end";
}

这将要求编译器将a的值放入寄存器edx(由d约束字母发出信号),然后将%edx替换为asm块%0(指操作数0),最后再次从%edx写回a+修饰符表示读写操作数。因此,此代码将打印start03end

如评论中所述,请确保您确实需要内联汇编,而不能使用矢量支持,内在函数或单独的汇编模块。