匯編語(yǔ)言的種類
- 目前討論比較多的匯編語(yǔ)言有:
- 8086 匯編(8086處理器是16bit 的 CPU)
- Win32 匯編
- Win64 匯編
- ARM 匯編
| 架構(gòu) | 設(shè)備 |
|---|---|
| armv6 | iPhone, iPhone2, iPhone3G, 第一代、第二代 iPod Touch |
| armv7 | iPhone3GS, iPhone4, iPhone4S,iPad, iPad2, iPad3(The New iPad), iPad mini, iPod Touch 3G, iPod Touch4 |
| armv7s | iPhone5, iPhone5C, iPad4(iPad with Retina Display) |
| arm64 | iPhone5S 以后 iPhoneX , iPad Air, iPad mini2以后 |
必要常識(shí):
- 首先了解 CPU 等硬件結(jié)構(gòu)
-
APP/程序的執(zhí)行過(guò)程15193672391363.jpg
- 硬件相關(guān)的最為重要的是 CPU 和內(nèi)存
- 匯編中,大部分指令都是和 CPU、內(nèi)存相關(guān)的
總線

CPU正面-A11處理器

CPU背面-管腳
- 每一個(gè) CPU 芯片都有許多管腳,這些管腳和總線相連,CPU 通過(guò)總線跟外部器件進(jìn)行交互
- 總線:一根根導(dǎo)線的集合
- 總線的分類:
- 地址總線-
- 它的寬度決定了 CPU 的尋址能力
- 8086的地址總線寬度是20,所以尋址能力是1M(2^20)
- 數(shù)據(jù)總線
- 它的寬度決定了 CPU 的單次數(shù)據(jù)傳送量,也就是數(shù)據(jù)傳送速度
- 8086的數(shù)據(jù)總線寬度為16,所以單詞最大傳遞2個(gè)字節(jié)的數(shù)據(jù)
- 控制總線
-
它的寬度決定了 CPU 對(duì)其他器件的控制能力、能有多少種控制
-
- 地址總線-
內(nèi)存
各類存儲(chǔ)區(qū)的邏輯連接
各類存儲(chǔ)器的邏輯連接-物理地址對(duì)應(yīng)圖
各類存儲(chǔ)器的物理地址情況
內(nèi)存地址空間的大小受CPU地址總線寬度的限制。8086的地址總線寬度為20,可以定位2^20個(gè)不同的內(nèi)存單元(內(nèi)存地址范圍0x00000~0xFFFFF),所以8086的內(nèi)存空間大小為1MB
0x00000~0x9FFFF:主存儲(chǔ)器??勺x可寫(xiě)
0xA0000~0xBFFFF:向顯存中寫(xiě)入數(shù)據(jù),這些數(shù)據(jù)會(huì)被顯卡輸出到顯示器??勺x可寫(xiě)
0xC0000~0xFFFFF:存儲(chǔ)各種硬件\系統(tǒng)信息。只讀
數(shù)據(jù)的寬度
數(shù)學(xué)上的數(shù)字,是沒(méi)有大小限制的,可以無(wú)限的大。但在計(jì)算機(jī)中,由于受硬件的制約,數(shù)據(jù)都是有長(zhǎng)度限制的(我們稱為數(shù)據(jù)寬度),超過(guò)最多寬度的數(shù)據(jù)會(huì)被丟棄。
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int test() {
int temp = 0x1ffffffff;
return temp;
}
int main(int argc, char * argv[]) {
printf("%x\n", test());
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
計(jì)算機(jī)中常見(jiàn)的數(shù)據(jù)寬度
- 位(Bit): 1個(gè)位就是1個(gè)二進(jìn)制位.0或者1
- 字節(jié)(Byte): 1個(gè)字節(jié)由8個(gè)Bit組成(8位).內(nèi)存中的最小單元Byte.
- 字(Word): 1個(gè)字由2個(gè)字節(jié)組成(16位),這2個(gè)字節(jié)分別稱為高字節(jié)和低字節(jié).
- 雙字(Doubleword): 1個(gè)雙字由兩個(gè)字組成(32位)
寄存器
內(nèi)部部件之間由總線連接

- 對(duì)程序員來(lái)說(shuō),CPU中最主要部件是寄存器,可以通過(guò)改變寄存器的內(nèi)容來(lái)實(shí)現(xiàn)對(duì)CPU的控制
- 不同的CPU,寄存器的個(gè)數(shù)、結(jié)構(gòu)是不相同的
通用寄存器
- ARM64擁有有31個(gè)64位的通用寄存器 x0 到 x30,這些寄存器通常用來(lái)存放一般性的數(shù)據(jù),稱為通用寄存器(有時(shí)也有特定用途)
- 那么w0 到 w28 這些是32位的. 因?yàn)?4位CPU可以兼容32位.所以可以只使用64位寄存器的低32位
-
比如 w0 就是 x0的低32位
- 通常,CPU會(huì)先將內(nèi)存中的數(shù)據(jù)存儲(chǔ)到通用寄存器中,然后再對(duì)通用寄存器中的數(shù)據(jù)進(jìn)行運(yùn)算
-
假設(shè)內(nèi)存中有塊紅色內(nèi)存空間的值是3,現(xiàn)在想把它的值加1,并將結(jié)果存儲(chǔ)到藍(lán)色內(nèi)存空間
- CPU首先會(huì)將紅色內(nèi)存空間的值放到X0寄存器中:mov X0,紅色內(nèi)存空間
- 然后讓X0寄存器與1相加:add X0,1
- 最后將值賦值給內(nèi)存空間:mov 藍(lán)色內(nèi)存空間,X0
pc寄存器(program counter)
- 為指令指針寄存器,它指示了CPU當(dāng)前要讀取指令的地址
- 在內(nèi)存或者磁盤上,指令和數(shù)據(jù)沒(méi)有任何區(qū)別,都是二進(jìn)制信息
- CPU在工作的時(shí)候把有的信息看做指令,有的信息看做數(shù)據(jù),為同樣的信息賦予了不同的意義
- 比如 1110 0000 0000 0011 0000 1000 1010 1010
- 可以當(dāng)做數(shù)據(jù) 0xE003008AA
- 也可以當(dāng)做指令 mov x0, x8
- CPU根據(jù)什么將內(nèi)存中的信息看做指令?
- CPU將pc指向的內(nèi)存單元的內(nèi)容看做指令
- 如果內(nèi)存中的某段內(nèi)容曾被CPU執(zhí)行過(guò),那么它所在的內(nèi)存單元必然被pc指向過(guò)
bl指令
- CPU從何處執(zhí)行指令是由pc中的內(nèi)容決定的,我們可以通過(guò)改變pc的內(nèi)容來(lái)控制CPU執(zhí)行目標(biāo)指令
- ARM64提供了一個(gè)mov指令(傳送指令),可以用來(lái)修改大部分寄存器的值,比如
mov x0,#10、mov x1,#20
- 但是,mov指令不能用于設(shè)置pc的值,ARM64沒(méi)有提供這樣的功能
- ARM64提供了另外的指令來(lái)修改pc的值,這些指令統(tǒng)稱為轉(zhuǎn)移指令,最簡(jiǎn)單的是bl指令



