在網(wǎng)上看到一篇關(guān)于ARM的介紹(比較老了),比較基礎(chǔ),容易理解。遂做了下翻譯,加深下自己對(duì)ARM的了解。雖然開(kāi)發(fā)中不太接觸,但是覺(jué)得了解下還是比較有意義的。當(dāng)然如果是做逆向,那就另當(dāng)別論了: )
概述
發(fā)布至今的iOS設(shè)備中的處理器都是基于ARM架構(gòu)的。你會(huì)發(fā)現(xiàn),這個(gè)架構(gòu)和一些用于桌面設(shè)備的x86或者是PowerPC架構(gòu)有些不一樣。然而,這并不是什么特別的架構(gòu),且應(yīng)用廣泛:幾乎所有移動(dòng)電話(不只是智能電話)都是基于ARM架構(gòu)的;幾乎所有的iPods,以及MP3,PDA和PocketPC設(shè)備通常都是基于ARM的;任天堂自GBA以來(lái)的便攜設(shè)備也是基于ARM的。還有目前正在使用的部分TI和HP型號(hào)的圖形識(shí)別計(jì)算器也在使用它;(事實(shí)上,蘋(píng)果是ARM較早的投資方)。這還只是一小部分,還有無(wú)數(shù)的ARM處理器用在嵌入式設(shè)備上。
ARM處理器因小尺寸、低功耗、性能強(qiáng)的特點(diǎn)而聞名。ARM架構(gòu)是小端(little-endian)即低位字節(jié)排在內(nèi)存的低地址端(至少在iOS平臺(tái)是這樣),和x86一樣。它和MIPS、PowerPC等一樣用的都是RISC,并且很長(zhǎng)時(shí)間都是32位,但是后來(lái)有了叫做ARM64的64位擴(kuò)展。
特別要注意一點(diǎn),模擬器不會(huì)執(zhí)行ARM代碼,因?yàn)橛媚M器的時(shí)候編譯的是x86的代碼,是用于在mac上本地執(zhí)行的。
ARM的版本
ARMv7, ARM11, Cortex A8 and A4
隨著時(shí)間的推移ARM架構(gòu)推出了一系列不同的版本,每個(gè)版本都添加了一些新指令和改進(jìn),同時(shí)向后兼容前一個(gè)版本。第一臺(tái)iPhone包含了一個(gè)實(shí)現(xiàn)了ARMv6的處理器,后來(lái)的設(shè)備包含了支持ARMv7的處理器。所以當(dāng)你編譯代碼時(shí),根據(jù)你指定目標(biāo)架構(gòu)版本,編譯器會(huì)生成架構(gòu)版本相對(duì)應(yīng)的指令。匯編程序也是一樣,編譯器會(huì)檢查所使用的指令是否包含在所指定的架構(gòu)版本中。最終,你會(huì)獲得針對(duì)指定架構(gòu)生成的目標(biāo)代碼。目標(biāo)文件和可執(zhí)行文件實(shí)際上會(huì)被標(biāo)記上他們所針對(duì)的架構(gòu),可以使用如下命令來(lái)檢查目標(biāo)文件所使用的架構(gòu)版本。
$ otool -vh foo.o
不要把ARMv6\ARMv7 和 ARM6\ARM7搞混了,后者是老的ARM處理器型號(hào),而前者是架構(gòu)版本。
處理器核心和芯片系統(tǒng)(Soc)
然而,我們并不能說(shuō)iPhone有一個(gè)"ARMv6的處理器",因?yàn)锳RMv6并不是指一個(gè)特定的處理器,只是說(shuō)處理器能夠運(yùn)行這個(gè)架構(gòu)的指令集,而并沒(méi)有做任何特定的實(shí)現(xiàn)。用于最早的iPhone的處理器核心是通過(guò)ARM11實(shí)現(xiàn)的。正如之前所提到的,這個(gè)處理器實(shí)現(xiàn)了ARMv6。隨后的設(shè)備使用過(guò)ARM11,直到iPhone 3GS為止,它使用的是Cortex A8處理器核心。再后來(lái)iOS的設(shè)備開(kāi)始使用更加神秘的,由蘋(píng)果自己的相關(guān)部門(mén)研發(fā)設(shè)計(jì)的處理器。如果你想知道某臺(tái)設(shè)備使用了哪個(gè)處理器,可以參考iOS Support Matrix
你可能會(huì)說(shuō)iPad和iPhone4都是A4的處理器,而不是Cortex A8!恩。。A4實(shí)際上是指芯片上的整個(gè)應(yīng)用系統(tǒng)(每個(gè)芯片都有一個(gè)芯片系統(tǒng)),它包含的不單單是CortexA8核心,同樣也包含圖形硬件,以及視頻和音頻解碼器加速器,和其他的數(shù)字模塊。芯片系統(tǒng)和處理器核心是有很大區(qū)別的,處理器核心不會(huì)占用晶片的絕大部分空間。
那么你該怎么檢測(cè)設(shè)備所支持的架構(gòu)版本,以便于你可以利用ARMv7的特性(如果有的話),亦或者你想防止你的代碼運(yùn)行在老設(shè)備上。BUT,你不需要這么做。因?yàn)槟愕拇a編譯了兩次,一次是針對(duì)ARMv6的,一次是針對(duì)ARMv7的,兩個(gè)可執(zhí)行文件會(huì)一起放到一個(gè)fat binary文件中(fat binary是一個(gè)包含多種類(lèi)型處理器指令集的文件),并且在運(yùn)行的時(shí)候設(shè)備會(huì)自己選擇他所支持的那部分執(zhí)行。是的,Mach-O fat binary不只是為了區(qū)分不同的處理器架構(gòu)(比如,PowerPC和Intel,生成的是一個(gè)通用的二進(jìn)制文件),或者一個(gè)架構(gòu)下的32位和64位,而且還有同個(gè)架構(gòu)下的兩個(gè)變體(CPU的子類(lèi)型,從Mach-O層面看)。從一個(gè)程序員的角度看,這每件事都是在編譯時(shí)決定的。
條件執(zhí)行
ARM架構(gòu)的一個(gè)有趣的特性是,大多數(shù)指令都是條件執(zhí)行的,如果條件為假,指令就沒(méi)有效果。這就能允許簡(jiǎn)短的if代碼塊實(shí)現(xiàn)得更有效,通常的方法是當(dāng)if條件為假則跳到代碼塊之后,但是現(xiàn)在代碼塊中的指令已經(jīng)被條件化了,節(jié)省一個(gè)分支。
如果使代碼更高效只是由于編譯器的一個(gè)特性我就不會(huì)提及這個(gè),而我現(xiàn)在提及它是因?yàn)樵谡{(diào)試時(shí)這可能會(huì)讓你覺(jué)得奇怪。事實(shí)上,有時(shí)候當(dāng)你知道if代碼塊條件為假,但你仍然看到debugger進(jìn)去了,或者if-else兩個(gè)代碼塊都進(jìn)了!這是因?yàn)樘幚砥麟m然經(jīng)過(guò)了代碼塊里的代碼,但是實(shí)際上不會(huì)執(zhí)行,原因就是代碼塊被條件化了,判斷的是代碼塊本身。
ARM64消除了條件執(zhí)行(只有幾個(gè)簡(jiǎn)單的指令仍然可以條件執(zhí)行)
Thumb
Thumb指令集是ARM指令集的一個(gè)子集,指令被壓縮到了16位(所有ARM指令都是32位的,Thumb仍舊是32位的架構(gòu),只是指令所占用的空間小了)。這并不是一個(gè)不同的架構(gòu),而應(yīng)該看作是大多數(shù)常用ARM指令和功能的一個(gè)簡(jiǎn)寫(xiě)。優(yōu)勢(shì)很明顯,能減少代碼的占用空間,節(jié)省內(nèi)存,緩存以及代碼帶寬。這對(duì)一些微控制器類(lèi)型的應(yīng)用是非常有用的。在iOS設(shè)備中也同樣有用,在Xcode中默認(rèn)是啟用Thumb指令的。代碼尺寸減小這點(diǎn)不錯(cuò),但是并沒(méi)有達(dá)到縮小50%的效果,因?yàn)橛袝r(shí)候一個(gè)ARM指令需要兩條Thumb指令來(lái)完成。ARM和Thumb指令不能混合,處理器在從執(zhí)行一個(gè)到另一個(gè)指令時(shí)需要切換模式,這只會(huì)在調(diào)用函數(shù)和函數(shù)返回時(shí)發(fā)生。
ARMv7包含Thumb-2,一個(gè)Thumb指令集的擴(kuò)展,添加了支持條件化執(zhí)行和32位的Thumb指令,這就能允許訪問(wèn)所以ARM寄存器。這相當(dāng)于無(wú)損耗得縮小了代碼的大小,但是在ARMv6上Thumb的表現(xiàn)會(huì)有些缺點(diǎn),所以在Xcode的build settings中使用條件來(lái)設(shè)置在ARMv7下啟用(現(xiàn)在應(yīng)該沒(méi)有這種問(wèn)題)。ARM64是一個(gè)新的指令集,所有指令還是32位的。
對(duì)齊
關(guān)于對(duì)齊,只有一點(diǎn)要說(shuō)的,在iOS平臺(tái)上支持不對(duì)齊的訪問(wèn),但是肯定比對(duì)齊的訪問(wèn)要慢,慢很多。要想具體了解的,可以參考這篇。
以上就是對(duì)ARM架構(gòu)大體的介紹,希望對(duì)你有幫助。