1

这是 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.
  1. 有人可以解释一下偏移量 +28,+32 的指令在做什么吗?在 +28 时,r12 的值为 0(设置为 +12),因此看起来 r12 被设置为(在 C 表示法中)*(pc + 4)。在 +32 时,r12 设置为 *(pc + r12) - 请注意,该指令未编译 - 请参见下面的 #3。+36 处的 'b' 跳转到 +44,返回到 r12 中的地址。那么 +28 和 +32 将什么值加载到 r12 中?

  2. +40 处的 cfldrdeq 指令有什么作用?我检查了 ARM 指令集并进行了搜索,但没有找到任何东西。

  3. 我使用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 supportcfldrdeq mvd15,[r12],#992'

4

1 回答 1

2

如果您了解有关读取 PC 的小问题,那就更有意义了:大多数读取PC的指令都会看到 address_of_current_instruction+8 的值(拇指模式下的 +4 除外,而ldm在 ARM 模式下可能是 +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

我不知道为什么在andsyscall()之间的地方“foo”的反汇编,导致分支超过非指令“foo”。ldr r12,[pc,r12]bx r12

还值得一提的是,简单地粘贴显示的代码几乎肯定行不通:您没有指向系统调用实际实现的重定位(在调试器中,一步过去bx r12,您应该到达那里);你只会分支到一些随机的地址。

错误“不能使用 PC 相对寻址的寄存器索引”显然是因为您在 Thumb 模式下编译(列表是 ARM 代码)。至于cfldrdeq,我相信它只是一个条件cfldrd指令(“eq”是一个条件代码),谷歌建议它与 Cirrus Logic“Maverick”处理器系列有关。

于 2012-10-09T01:03:12.807 回答