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

joh*_*ohn 8 assembly gcc inline-assembly

这看起来不太友好:

__asm("command 1"
      "command 2"
      "command 3");
Run Code Online (Sandbox Code Playgroud)

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

另外......因为多行字符串文字在GCC中不起作用,所以我也不能作弊.

jyz*_*jyz 11

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

非常丑陋的方式:

asm("xor %eax,%eax");
asm("mov $0x7c802446, %ebx");
asm("mov $500, %ax");
asm("push %eax");
asm("call *%ebx");
Run Code Online (Sandbox Code Playgroud)

或者这个不那么难看的人:

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

  • `\ t \n`的替代是分号以分隔指令.`\ t \n`更好,因为产生的asm输出不会是一团糟.通常使用`"insn \n\t"```insn2 \n\t"等等,让字符串连接起作用,而不是用反斜杠结束每一行. (3认同)

Cir*_*四事件 5

C++ 多行字符串文字

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

主程序

#include <cassert>
#include <cinttypes>

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

编译并运行:

g++ -o main -pedantic -std=c++11 -Wall -Wextra main.cpp
./main
Run Code Online (Sandbox Code Playgroud)

另请参阅:C++ 多行字符串文字

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

主文件

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

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

编译并运行:

gcc -o main -pedantic -std=gnu99 -Wall -Wextra main.c
./main
Run Code Online (Sandbox Code Playgroud)

也可以看看: 如何在 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 指令是另一件您应该关注的事情:使用 GCC 在可执行文件中嵌入资源

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