簡體   English   中英

如何在 GCC C++ 中編寫多行內聯匯編代碼?

[英]How to write multiline inline assembly code in GCC C++?

這看起來不太友好:

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

我真的必須在每一行周圍加上雙引號嗎?

另外...由於多行字符串文字在 GCC 中不起作用,我也無法欺騙。

我總是在 Internet 上找到一些示例,該人手動插入制表符和換行符而不是 \\t 和 \\n,但是它對我不起作用。 不太確定您的示例是否可以編譯..但這就是我的做法:

asm volatile(           // note the backslash line-continuation
   "xor %eax,%eax          \n\t\
    mov $0x7c802446, %ebx  \n\t\
    mov $1000, %ax         \n\t\
    push %eax              \n\t\
    call *%ebx             \n\t\
    add $4, %esp           \n\t\
    "
    : "=a"(retval)        // output in EAX: function return value
    :
    : "ecx", "edx", "ebx"   // tell compiler about clobbers
  // Also x87 and XMM regs should be listed.
 );

或者在每一行周圍加上雙引號,而不是使用\\ line-continuation。 C 字符串文字僅由空格(包括換行符)單獨連接成一個長字符串文字。 (這就是為什么你需要\\n在里面,所以當它被匯編程序看到時它是單獨的行)。

這不那么難看,並且可以在每一行上放置 C 注釋。

asm volatile(
    "xor %eax,%eax          \n\t"
    "mov $0x7c802446, %ebx  \n\t"
    "mov $1000, %ax         \n\t"
    "push %eax              \n\t"  // function arg
    "call *%ebx             \n\t"
    "add $4, %esp           \n\t"  // rebalance the stack: necessary for asm statements
  : "=a"(retval)
  :
  : "ecx", "edx", "ebx"    // clobbers.  Function calls themselves kill EAX,ECX,EDX
  // function calls also clobber all x87 and all XMM registers, omitted here
);

C++ 多行字符串文字

有趣的是這個問題如何指向我的答案:

主程序

#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++ 多行字符串文字

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);
}

編譯並運行:

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

另請參閱: 如何在 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 在可執行文件中嵌入資源

該程序集將在一個單獨的文件中,因此它不是一個直接的答案,但仍然值得了解。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM