如何在GCC C ++中编写多行内联汇编代码?

时间:2010-09-08 08:47:56

标签: gcc assembly inline-assembly

这看起来不太友好:

__asm("command 1"
      "command 2"
      "command 3");

我真的必须在每一行都加上双引号吗?

另外......由于多行字符串文字在GCC中不起作用,我也不能对此作弊。

2 个答案:

答案 0 :(得分:10)

我总是在互联网上找到一些例子,那个人手动插入一个标签和换行符而不是\ t和\ n,但它对我不起作用。不确定你的例子是否编译..但这就是我的方式:

非常丑陋的方式:

asm("xor %eax,%eax");
asm("mov $0x7c802446, %ebx");
asm("mov $500, %ax");
asm("push %eax");
asm("call *%ebx");

或者这个不那么丑陋的人:

asm("xor %eax,%eax         \t\n\
    mov $0x7c802446, %ebx  \t\n\
    mov $1000, %ax         \t\n\
    push %eax              \t\n\
    call *%ebx             \t\n\
    ");

答案 1 :(得分:2)

C ++多行字符串文字

有趣的是这个问题如何使我指向答案:

main.cpp

#include <cassert>
#include <cinttypes>

int main() {
    uint64_t io = 0;
    __asm__ (
        R"(
incq %0
incq %0
)"
        : "+m" (io)
        :
        :
    );
    assert(io == 2);
}

编译并运行:

g++ -o main -pedantic -std=c++11 -Wall -Wextra main.cpp
./main

另请参阅:C++ multiline string literal

GCC还添加了与C扩展相同的语法,您只需要使用-std=gnu99而不是-std=c99

main.c

#include <assert.h>
#include <inttypes.h>

int main(void) {
    uint64_t io = 0;
    __asm__ (
        R"(
incq %0
incq %0
)"
        : "+m" (io)
        :
        :
    );
    assert(io == 2);
}

编译并运行:

gcc -o main -pedantic -std=gnu99 -Wall -Wextra main.c
./main

另请参阅:How to split a string literal across multiple lines in C / Objective-C?

此方法的一个缺点是我看不到如何在程序集中添加C预处理程序宏,因为它们未在字符串内部扩展,另请参见:Multi line inline assembly macro with strings

在Ubuntu 16.04,GCC 6.4.0,binutils 2.26.1上进行了测试。

.incbin

如果您要使用大块的汇编代码,则此GNU GAS指令是您应该注意的另一件事:Embedding resources in executable using GCC

程序集将放在单独的文件中,因此不是直接答案,但仍然值得了解。