[英]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.