由0和1組成的機器指令程序員
使用助記符代替機器語言 如:緩存
C\C++\Java\OC\Swift,更加接近人類的天然語言 好比C語言:sass
咱們的代碼在終端設備上是這樣的過程:安全
彙編語言與機器語言一一對應,每一條機器指令都有與之對應的彙編指令 彙編語言能夠經過編譯獲得機器語言,機器語言能夠經過反彙編獲得彙編語言 高級語言能夠經過編譯獲得彙編語言 \ 機器語言,但彙編語言\機器語言幾乎不可能還原成高級語言markdown
最後來句裝13的話架構
越底層越單純!真正的程序員都須要瞭解的一門很是重要的語言,彙編!函數
架構 | 設備 |
---|---|
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之後 |
舉個例子post
作個小練習性能
答案學習
內存
內存地址空間的大小受CPU地址總線寬度的限制。8086的地址總線寬度爲20,能夠定位220個不一樣的內存單元(內存地址範圍0x00000~0xFFFFF),因此8086的內存空間大小爲1MB
0x00000~0x9FFFF:主存儲器。可讀可寫
0xA0000~0xBFFFF:向顯存中寫入數據,這些數據會被顯卡輸出到顯示器。可讀可寫
0xC0000~0xFFFFF:存儲各類硬件\系統信息。只讀
學習進制的障礙
不少人學很差進制,緣由是總以十進制爲依託去考慮其餘進制,須要運算的時候也老是先轉換成十進制,這種學習方法是錯誤的. 咱們爲何必定要轉換十進制呢?僅僅是由於咱們對十進制最熟悉,因此才轉換. 每一種進制都是完美的,想學好進制首先要忘掉十進制,也要忘掉進制間的轉換!
進制的定義
作個練習
若是咱們自定義十進制由10個符號組成: 0 1 3 2 8 A B E S 7 逢十進一,這樣定義十進制: 1 + 1 = 3!就對了!
這樣的目的何在?
傳統咱們定義的十進制和自定義的十進制不同.那麼這10個符號若是咱們不告訴別人這個符號表,別人是沒辦法拿到咱們的具體數據的!用於加密!
十進制由十個符號組成,逢十進一,符號是能夠自定義的!!
進制的運算
2 + 3 = __ , 2 * 3 = __ ,4 + 5 = __ ,4 * 5 = __.
277 + 333 = __ , 276 * 54 = __ , 237 - 54 = __ , 234 / 4 = __ .
八進制加法表
0 1 2 3 4 5 6 7
10 11 12 13 14 15 16 17
20 21 22 23 24 25 26 27
...
1+1 = 2
1+2 = 3 2+2 = 4
1+3 = 4 2+3 = 5 3+3 = 6
1+4 = 5 2+4 = 6 3+4 = 7 4+4 = 10
1+5 = 6 2+5 = 7 3+5 = 10 4+5 = 11 5+5 = 12
1+6 = 7 2+6 = 10 3+6 = 11 4+6 = 12 5+6 = 13 6+6 = 14
1+7 = 10 2+7 = 11 3+7 = 12 4+7 = 13 5+7 = 14 6+7 = 15 7+7 = 16
複製代碼
八進制乘法表
0 1 2 3 4 5 6 7 10 11 12 13 14 15 16 17 20 21 22 23 24 25 26 27...
1*1 = 1
1*2 = 2 2*2 = 4
1*3 = 3 2*3 = 6 3*3 = 11
1*4 = 4 2*4 = 10 3*4 = 14 4*4 = 20
1*5 = 5 2*5 = 12 3*5 = 17 4*5 = 24 5*5 = 31
1*6 = 6 2*6 = 14 3*6 = 22 4*6 = 30 5*6 = 36 6*6 = 44
1*7 = 7 2*7 = 16 3*7 = 25 4*7 = 34 5*7 = 43 6*7 = 52 7*7 = 61
複製代碼
實戰四則運算
二進制的簡寫形式
二進制: 1 0 1 1 1 0 1 1 1 1 0 0
三個二進制一組: 101 110 111 100
八進制: 5 6 7 4
四個二進制一組: 1011 1011 1100
十六進制: b b c
複製代碼
二進制:從0 寫到 1111 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111 這種二進制使用起來太麻煩,改爲更簡單一點的符號: 0 1 2 3 4 5 6 7 8 9 A B C D E F 這就是十六進制了
數學上的數字,是沒有大小限制的,能夠無限的大。但在計算機中,因爲受硬件的制約,數據都是有長度限制的(咱們稱爲數據寬度),超過最多寬度的數據會被丟棄。
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int test(){
int cTemp = 0x1FFFFFFFF;
return cTemp;
}
int main(int argc, char * argv[]) {
printf("%x\n",test());
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
複製代碼
那麼計算機存儲數據它會分爲有符號數和無符號數.那麼關於這個看圖就理解了!
無符號數,直接換算!
有符號數:
正數: 0 1 2 3 4 5 6 7
負數: F E D B C A 9 8
-1 -2 -3 -4 -5 -6 -7 -8
複製代碼
自定義進制符號 練習
十進制: 0 1 2 3 4 5 6 7 8 9
自定義: 2 9 1 7 6 5 4 8 3 A
92 99 91 97 96 95 94 98 93 9A
12 19 11 17 16 15 14 18 13 1A
72 79 71 77 76 75 74 78 73 7A
62 69 61 67 66 65 64 68 63 6A
52 59 51 57 56 55 54 58 53 5A
42 49 41 47 46 45 44 48 43 4A
82 89 81 87 86 85 84 88 83 8A
32 39 31 37 36 35 34 38 33 3A
922
複製代碼
那麼剛纔經過10進制運算能夠轉化10進制而後查表!可是若是是其餘進制.咱們就不能轉換,要直接學會查表
十進制: 0 1 2 3 4 5 6 7 8
自定義: 2 9 1 7 6 5 4 8 3
92 99 91 97 96 95 94 98 93
12 19 11 17 16 15 14 18 13
72 79 71 77 76 75 74 78 73
62 69 61 67 66 65 64 68 63
52 59 51 57 56 55 54 58 53
42 49 41 47 46 45 44 48 43
82 89 81 87 86 85 84 88 83
32 39 31 37 36 35 34 38 33
922
複製代碼
內部部件之間由總線鏈接
CPU除了有控制器、運算器還有寄存器。其中寄存器的做用就是進行數據的臨時存儲。
CPU的運算速度是很是快的,爲了性能CPU在內部開闢一小塊臨時存儲區域,並在進行運算時先將數據從內存複製到這一小塊臨時存儲區域中,運算時就在這一小快臨時存儲區域內進行。咱們稱這一小塊臨時存儲區域爲寄存器。
對於arm64系的CPU來講, 若是寄存器以x開頭則代表的是一個64位的寄存器,若是以w開頭則代表是一個32位的寄存器,在系統中沒有提供16位和8位的寄存器供訪問和使用。其中32位的寄存器是64位寄存器的低32位部分並非獨立存在的。
浮點和向量寄存器
由於浮點數的存儲以及其運算的特殊性,CPU中專門提供浮點數寄存器來處理浮點數
如今的CPU支持向量運算.(向量運算在圖形處理相關的領域用得很是的多)爲了支持向量計算系統了也提供了衆多的向量寄存器.
通用寄存器
注意: 瞭解過8086彙編的同窗知道,有一種特殊的寄存器段寄存器:CS,DS,SS,ES四個寄存器來保存這些段的基地址,這個屬於Intel架構CPU中.在ARM中並無
pc寄存器(program counter)
高速緩存
iPhoneX上搭載的ARM處理器A11它的1級緩存的容量是64KB,2級緩存的容量8M.
CPU每執行一條指令前都須要從內存中將指令讀取到CPU內並執行。而寄存器的運行速度相比內存讀寫要快不少,爲了性能,CPU還集成了一個高速緩存存儲區域.當程序在運行時,先將要執行的指令代碼以及數據複製到高速緩存中去(由操做系統完成).CPU直接從高速緩存依次讀取指令來執行.
bl指令
CPU從何處執行指令是由pc中的內容決定的,咱們能夠經過改變pc的內容來控制CPU執行目標指令
ARM64提供了一個mov指令(傳送指令),能夠用來修改大部分寄存器的值,好比
可是,mov指令不能用於設置pc的值,ARM64沒有提供這樣的功能
ARM64提供了另外的指令來修改PC的值,這些指令統稱爲轉移指令,最簡單的是bl指令
bl指令 -- 練習
如今有兩段代碼!假設程序先執行A,請寫出指令執行順序.最終寄存器x0的值是多少?
_A:
mov x0,#0xa0
mov x1,#0x00
add x1, x0, #0x14
mov x0,x1
bl _B
mov x0,#0x0
ret
_B:
add x0, x0, #0x10
ret
複製代碼
新建Xcode工程命名爲彙編01
,新建Empty文件命名爲asm.s
在asm.s中寫代碼
.text
.global _A,_B
_A:
mov x0, #0xa0
mov x1, #0x00
add x1, x0, #0x14
mov x0,x1
bl _B
mov x0, #0x0
ret
_B:
add x0, x0, #0x10
ret
複製代碼
咱們能夠看到這個文件是會正常參加編譯的
在另外一個文件中嘗試調用_A
函數
假如沒有asm.s
文件的話A()
函數有聲明沒有實現是不能編譯經過的,咱們選擇真機嘗試編譯
選擇真機進行編譯,注意要用真機!!!!!
咱們發現是能夠編譯成功的,這就說明asm.s
文件中的_A
函數有效果了
勾選Debug -> always show disassembly
在A()
函數處打斷點並運行工程
注意工做臺選擇All Variables,Registers,Globals and Statics
這時咱們能夠查看寄存器信息
按住control
單步執行彙編指令並觀察寄存器x0
和x1
的值的變化
例如執行完指令mov x0,#0xa0
以後x0
寄存器的值變爲0xa0
可是執行到最後兩句指令時咱們發現進入了死循環,這是爲何呢???請聽下回分解