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 の値を認識します (thumb モードでは +4 を除き、ARM モードでは +8 または +12 IIRC のいずれかになる可能性があります)。 .ldm

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()「foo」を配置するための逆アセンブルが、非命令の「foo」に分岐する理由がわかりません。ldr r12,[pc,r12]bx r12

表示されているコードを単純に貼り付けるだけでは、ほぼ確実に機能しないことにも言及する価値があります。syscall の実際の実装を指す再配置がありません(デバッガーで、ステップを過ぎbx r12て、そこに到達する必要があります)。ランダムなアドレスに分岐するだけです。

「PC 相対アドレッシングでレジスタ インデックスを使用できません」というエラーは、Thumb モードでコンパイルしているためと思われます (リストは ARM コードです)。に関してはcfldrdeq、これは単なる条件付きcfldrd命令 (「eq」は条件コード) であり、Google は Cirrus Logic の「Maverick」プロセッサ シリーズに関連していると考えています。

于 2012-10-09T01:03:12.807 に答える