铿锵+;iOS+;汇编程序跳转:错误“;符号“上不支持的重新定位”;
我有ARM32的汇编代码,它在Android上编译得很好,但在iOS上,它在跳转指令上抛出错误“符号上不支持的重新定位”。对于Android64和iOS64,情况相同铿锵+;iOS+;汇编程序跳转:错误“;符号“上不支持的重新定位”;,ios,assembly,arm,clang,arm64,Ios,Assembly,Arm,Clang,Arm64,我有ARM32的汇编代码,它在Android上编译得很好,但在iOS上,它在跳转指令上抛出错误“符号上不支持的重新定位”。对于Android64和iOS64,情况相同 clang -target armv7m-none-ios-gnueabi "test.c" void func() { __反复无常 ( eor r0,0\n\t cmp r0,0\n\t “beq.done\n\t”/**/ eor r0,0\n\t “.done:\n\t” “bx lr\n\t” ); } 同时,没有问
clang -target armv7m-none-ios-gnueabi "test.c"
void func()
{
__反复无常
(
eor r0,0\n\t
cmp r0,0\n\t
“beq.done\n\t”/**/
eor r0,0\n\t
“.done:\n\t”
“bx lr\n\t”
);
}
同时,没有问题出现在锁紧螺栓。
我使用的是Clang编译器8.0.0。标签需要是本地的,即以大写的
L
开头。请注意,这与ELF目标不同,ELF目标中的本地标签以.L
开头
这段代码对我来说很好:
void func()
{
__asm__ volatile
(
"eor r0, 0 \n\t"
"cmp r0, 0 \n\t"
"beq Ldone \n\t" /*!!!*/
"eor r0, 0 \n\t"
"Ldone: \n\t"
"bx lr \n\t"
);
}
不过,作为旁注,您可能希望完全在汇编中编写函数,如下所示,因为据我所知,编译器不能保证不会在汇编之前或之后插入违背您假设的代码。所以我建议如下:
__asm__
(
"_func: \n"
"eor r0, 0 \n"
"cmp r0, 0 \n"
"beq Ldone \n"
"eor r0, 0 \n"
"Ldone: \n"
"bx lr \n"
);
为什么你需要asm?而且,零的
eor
似乎毫无意义。无论如何,试着改用本地标签。我有很多复杂的汇编代码。这个例子只是如何重现错误的一个小例子。没有eor,可以有任何指令。我怀疑eor
有什么不同。A可能只是一个beq.done。完成:
一般来说,我会避免使用带前导点的符号,因为指令通常采用这种形式,除非我知道这对汇编程序是安全的。你是对的。无论如何,这都不重要。可以用点来命名标签。但是,如果您将点更改为任何字符,情况将不会改变。@Jester:汇编程序必须将重新定位编码到对象文件中。如果出于某种原因,它认为分支目标距离不远,它可能会输出该消息。例如,对于ldr reg,=symbol^0x1234
,您可以获得类似这样的消息,因为地址XOR常量没有重新定位。但是我看不出这里有什么问题,除非这个内联多次,并且重复的标签最终给出了“错误”的错误消息。因此,可以使用%=
或其他任何方法向asm标签添加一个唯一的ID号,并将其称为.L
本地名称。@Listener:可能值得一提的是,这里的第一个示例被破坏了,因为它从内联asm中使用bx lr
,而没有使用asm goto
或\u builtin\u unreable()
在asm之后。如果它修改了r0
,它也会因为从clobber列表(扩展asm)中遗漏r0
而被破坏。而且它已经因使用cmp
(一个“cc”
clobber)重击条件代码而被破坏。在全局范围内使用asm
声明纯asm函数标签/符号是有效的,但是,如果您希望避免使用单独的.S
文件,那么您就不会从内联asm中获得任何好处(内联)。