我正在尝试使用内联汇编程序在代码部分中嵌入指向字符串的指针。但是gcc在符号名称的开头添加了一个$,导致链接错误。
这是一个最小的例子,
static const char str[] = "bar";
int main()
{
__asm__ __volatile__
(
"jmp 0f\n\t"
".long %0\n\t"
"0:"
:
: "i" ( str )
);
return 0;
}
使用
构建gcc -Wall -save-temps test.c -o test
给出错误
test.o: In function `main':
test.c:(.text+0x6): undefined reference to `$str'
查看.s临时文件,可以看到额外的$ preped到str
.file "test.c"
.section .rodata
.type str, @object
.size str, 4
str:
.string "bar"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
movq %rsp, %rbp
.cfi_offset 6, -16
.cfi_def_cfa_register 6
#APP
# 4 "test.c" 1
jmp 0f
.long $str
0:
# 0 "" 2
#NO_APP
movl $0, %eax
leave
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5"
.section .note.GNU-stack,"",@progbits
认为我正在以正确的方式这样做,因为相同的方法适用于ppc gcc,
<clip>
b 0f
.long str
0:
</clip>
然后,也许它只是“运气”它适用于ppc。问题是因为在使用AT&amp; T synax时$被用作immediates的前缀吗?
在这个简单的例子中,我可以通过在内联汇编程序中对符号名称“str”进行硬编码来解决这个问题,但实际上需要它作为内联汇编程序的输入约束。
有没有人对如何在x86目标上运行有任何想法?
谢谢,
- 卢克
答案 0 :(得分:0)
使用clang会发生同样的事情,可能是因为代码生成器不知道操作数是在.long中使用而不是作为立即指令操作数。您的代码尝试类似:
const char str[] = "bar";
#define string(str) __asm__ __volatile__ \
( \
"jmp 0f\n\t" \
".long " #str "\n\t" \
"0:" \
)
int main()
{
string(str);
return 0;
}
(我不得不删除str上的“static”,因为编译器将其优化为未被引用。)