这是iPhone上的syscall()反汇编。
(gdb) disass syscall
Dump of assembler code for function syscall:
0x3195fafc <syscall+0>: mov r12, sp
0x3195fb00 <syscall+4>: push {r4, r5, r6, r8}
0x3195fb04 <syscall+8>: ldm r12, {r4, r5, r6}
0x3195fb08 <syscall+12>: mov r12, #0 ; 0x0
0x3195fb0c <syscall+16>: svc 0x00000080
0x3195fb10 <syscall+20>: pop {r4, r5, r6, r8}
0x3195fb14 <syscall+24>: bcc 0x3195fb2c <syscall+48>
0x3195fb18 <syscall+28>: ldr r12, [pc, #4] ; 0x3195fb24 <syscall+40>
0x3195fb1c <syscall+32>: ldr r12, [pc, r12]
0x3195fb20 <syscall+36>: b 0x3195fb28 <syscall+44>
0x3195fb24 <syscall+40>: cfldrdeq mvd15, [r12], #992
0x3195fb28 <syscall+44>: bx r12
0x3195fb2c <syscall+48>: bx lr
End of assembler dump.
有人可以解释抵消+ 28,+ 32的指示吗?在+28,r12的值为0(设置为+12),因此看起来r12被设置为(以C表示法)*(pc + 4)。在+32,r12设置为*(pc + r12) - 请注意,该指令未编译 - 请参阅下面的#3。 +36处的'b'跳转到+44,返回到r12中的地址。那么通过+28&amp;和r12加载到r12的值是多少? 32
+40的cfldrdeq指令有什么作用?我检查了ARM指令集&amp;搜索它,但没有找到任何东西。
我使用 asm ()将此代码添加到我的C程序中。编译时,编译器会显示这些错误。知道怎么解决这个问题吗?
/var/folders/62/3px_xsd56ml5gz18lp8dptjc0000gv/T//ccDThXFx.s:7607:不能使用寄存器索引和PC相对寻址 - ldr r12,[pc,r12]'
/var/folders/62/3px_xsd56ml5gz18lp8dptjc0000gv/T//ccDThXFx.s:7609:selected processor does
not support
cfldrdeq mvd15,[r12],#992'
答案 0 :(得分:2)
如果您知道读取PC的小问题,那就更有意义了:大多数指令读取 PC 看到address_of_current_instruction + 8的值(除了+4 in拇指模式,ARM模式下的ldm
可能是+8或+12 IIRC。
cfldrdeq mvd15, [r12], #992
并不是指令;它是一个相对重定位,指向重定位DATA部分。在DATA部分,将有一个指向实际地址的动态重定位。典型的seudocode看起来像这样
ldr r12,[pc,#small_offset_to_foo]
ldr r12,[pc,r12]
bx r12
... a short distance away ...
foo:
int relative_offset_of_bar_from_the_second_ldr
... a galaxy far far away ...
bar:
int pointer_to_the_actual_syscall
我不知道为什么syscall()
的反汇编会在ldr r12,[pc,r12]
和bx r12
之间放置“foo”,导致分支超过非指令“foo”。
还值得一提的是,简单地粘贴显示的代码几乎肯定无法正常工作:您没有指向系统调用的实际实现的重定位(在调试器中,超过bx r12
,你应该到达那里);你只需要分支到一些随机的地址。
错误“无法使用PC相对寻址的寄存器索引”显然是因为您在Thumb模式下编译(列表是ARM代码)。至于cfldrdeq
,我认为它只是一个条件cfldrd
指令(“eq”是一个条件代码),谷歌建议它与Cirrus Logic“Maverick”处理器系列有关。