我正在尝试在gcc扩展的asm命令中使用.ascii
指令,但我不断收到编译器错误。扩展asm内指令的确切语法是什么?
我尝试了以下选项,但没有一个可行:
asm ("NOP;"
".ASCII ""ABC"""
);
我得到了“错误:行尾的垃圾,第一个无法识别的字符是'/'”
asm ("NOP;"
".ASCII "ABC""
);
我得到了错误:行尾的垃圾,第一个无法识别的字符是“/”“
asm ("NOP;"
.ASCII "ABC"
);
我在'/'标记'
之前得到了“错误:预期':'或')'答案 0 :(得分:2)
asm中的指令语法与编写GNU Assembler相同,因此您可以参考GNU Assembler手册获取相关语法。
示例:
#include <stdio.h>
int
main (void)
{
char *string;
asm (".pushsection .rodata\n"
"0:\n"
" .ascii \"Testing 1 2 3!\"\n"
" .popsection\n"
" mov $0b, %0\n":"=rm" (string));
puts (string);
}
在示例中,我们使用扩展的asm将字符串的地址复制到char *
,然后将其传递给puts以打印字符串。
需要将字符串放入相应的链接器部分,而不仅仅是添加到当前(通常是代码部分,即.text
)。因此,首先将希望字符串存储的部分推送到汇编程序的部分堆栈中。在这个例子中,我给它提供了大多数字符串存在的只读数据部分(.rodata
)。然后弹出部分堆栈中的部分以返回编译器离开的任何部分,并使用字符串地址执行操作。诀窍是使用像0
这样的本地标签来引用字符串,让汇编器和链接器为您计算偏移量。如果您是PIE或PIC,这可能需要更多工作,具体取决于您的参考文献变得多么复杂或需要重新定位。