2013-10-18 13 views
1

我很驚訝,搜索j__objc_msg發送在stackoverflow上返回0結果,谷歌似乎也不太瞭解它。根據它的disassembly,j__objc_msgSend只調用objc_msgSend,那麼爲什麼當我們已經有objc_msgSend時需要j__objc_msgSend?一般來說,j__objc_msgSend和objc_msgSend有什麼區別?j__objc_msgSend和objc_msgSend有什麼區別?

而在這screenshot具體來說,最右邊的分支以「End of Function」結尾,最左邊的分支結尾沒有「End of Function」結尾有什麼區別?它與j__objc_msg發送有什麼關係?

+0

[Apple的最新公共版本gcc](http://www.opensource.apple.com/tarballs/gcc/gcc-4061.tar.gz)中沒有關於j__objc_msgSend函數的參考。 –

回答

1
  1. 這是ARM RISC代碼,並首選的編程模式,ARM是相對 - 不使用絕對地址,一定要使用「IP +/-偏移」。在這裏,被調用的地址超出了直接調用或跳轉的範圍,並且編譯器使用了他能找到的最近的地址。它增加了一個額外的跳躍(或超過1!),但它是位置無關的。 (*)

    編譯器無法用簡單的指令構建跳轉到目標地址,因爲您無法立即將每個可能的2^32數字加載到RISC彙編中。

  2. 如果例程objc_msgSend自己的回報,那麼這相當於call objc_msgSend; return - 只是更短。從當前函數的角度來看,這兩種形式都會執行一次「返回」。


(*)您可以在拆卸截圖(??爲什麼不發短信?)是R12被加載與目標,現在的地址之間的差異看到。這種差異是由編譯器計算的;它確實是而不是顯示爲原始二進制中的減法,這是IDA的工作。然後將差異添加到當前地址 - 無論這是什麼!立即數objc_msgSend - 0x1AE030使用一個足夠小的位數在單個指令中加載到R12中(您應該熟悉ARM RISC'功能')。

如果您想知道j__label語法:這只是IDA,告訴您這是直接跳轉到已知標籤。據推測,如果你的代碼足夠長,你可能會發現這個標籤的距離又太大了,所以你可能會發現j__j__objc_msgSend