1

j__objc_msgSendを検索すると、stackoverflow で 0 の結果が返されることに驚いており、Google もそれをよく知らないようです。逆アセンブリによると、j__objc_msgSend は objc_msgSend のみを呼び出します。では、objc_msgSend が既にあるのに、なぜ j__objc_msgSend が必要なのですか? 一般的に、j__objc_msgSend と objc_msgSend の違いは何ですか?

具体的には、このスクリーンショットで、「関数の終了」で終わる一番右のブランチと、「関数の終了」なしで終わる一番左のブランチの違いは何ですか? j__objc_msgSendと何か関係がありますか?

4

1 に答える 1

1
  1. これは ARM RISC コードであり、ARM で推奨されるプログラミング モードは相対です。絶対アドレスを使用しないでください。常に「IP+/-offset」を使用してください。ここでは、呼び出されたアドレスが直接呼び出しまたはジャンプの範囲外であり、コンパイラは見つけた最も近いアドレスを使用しました。追加のジャンプ (または 1 つ以上!) を追加しますが、位置に依存しません。(*)

    コンパイラは、単純な命令ではターゲット アドレスへのジャンプを構築できません。これは、RISC アセンブリを使用して可能なすべての 2^32 数値をすぐにロードできないためです。

  2. ルーチンobjc_msgSendが独自に戻る場合、これはcall objc_msgSend; return-- と同等です。どちらの形式も、現在の関数の観点から、単一の「戻り」を行います。


(*) 逆アセンブルのスクリーンショット (なぜテキストではないのですか?) で、R12 がターゲットと現在のアドレスの違いで読み込まれることがわかります。この差はコンパイラによって計算されます。元のバイナリでは減算として表示されませ。これはIDA の仕事です。次に、差額が現在のアドレスに追加されます。これが何であれ! 即値objc_msgSend - 0x1AE030は、1 つの命令で R12 にロードするのに十分な少量のビットを使用します (よく知っている必要がある ARM RISC の「機能」)。

構文について疑問がある場合: これは単なる IDA であり、既知のラベルへの直接ジャンプであることを示しています。おそらく、コードが十分に長い場合、このラベルまでの距離が再び大きすぎることがわかり、.j__labelj__j__objc_msgSend

于 2013-10-21T20:32:05.477 に答える