b : bit ,?B : Byte , 8 bit = 1 Byte
M 是數量單位? 1024 = 1K , 1024K = 1M, 1024M = 1G
b(bit) 是一個二進制位,8bit = 1B, 1024B = 1KB(容量),?
帶寬給的是數量單位,比如 100M的帶寬(容量單位),換算成容量赎瞎,100 / 8 = 12.5 MB/s,(因為傳輸的是二進制數據)
尋址能力,2^20 = 1M 是數量單位宾茂,由于地址總線指向的是內存條塘安,與內存條的內存地址相鏈接农曲,這時數量單位和容量單位是一致的链烈,當尋址能力是1M,容量單位也是1M
因為內存條的最小單位是字節(jié) (8bit = 1B)撕贞,這時數量和容量能過一一對應,所以當尋址能力為1M時测垛,內存中能夠尋找的容量為 1MB
進制
學習進制的障礙
很多人學不好進制,原因是總以十進制為依托去考慮其他進制秧均,需要運算的時候也總是先轉換成十進制食侮,這種學習方法是錯誤的.
我們?yōu)槭裁匆欢ㄒD換十進制呢?僅僅是因為我們對十進制最熟悉目胡,所以才轉換.
每一種進制都是完美的,想學好進制首先要忘掉十進制锯七,也要忘掉進制間的轉換!
進制的定義
八進制由8個符號組成:0 1 2 3 4 5 6 7 逢八進一
十進制由10個符號組成:0 1 2 3 4 5 6 7 8 9逢十進一
N進制就是由N個符號組成:逢N進一
計算機中常見的數據寬度
位(Bit): 1個位就是1個二進制位.0或者1
字節(jié)(Byte): 1個字節(jié)由8個Bit組成(8位).內存中的最小單元Byte.
字(Word): 1個字由2個字節(jié)組成(16位),這2個字節(jié)分別稱為高字節(jié)和低字節(jié).
雙字(Doubleword): 1個雙字由兩個字組成(32位)
general purpose register 寄存器 誉己,cpsr? 標記寄存器
數據在計算機中是有寬度的
當在ffffffff前面加個值后眉尸,數據會丟失,所以數據是有寬度的
16進制 0xffffffff,是4個字節(jié)的1巨双,(1111 1111 1111 1111 1111 1111 1111 1111)一個字節(jié)是8個bit
CPU&寄存器
如果寄存器以x開頭則表明的是一個64位的寄存器噪猾,代表著有64根總線,數據吞吐量為64 / 8 = 8 個字節(jié)筑累。
如果以w開頭則表明是一個32位的寄存器袱蜡,在系統中沒有提供16位和8位的寄存器供訪問和使用。其中32位的寄存器是64位寄存器的低32位部分并不是獨立存在的慢宗。
對程序員來說坪蚁,CPU中最主要部件是寄存器奔穿,可以通過改變寄存器的內容來實現對CPU的控制, 不同的CPU敏晤,寄存器的個數贱田、結構是不相同的
浮點和向量寄存器
因為浮點數的存儲以及其運算的特殊性,CPU中專門提供浮點數寄存器來處理浮點數
浮點寄存器 64位: D0 - D31 32位: S0 - S31
現在的CPU支持向量運算.(向量運算在圖形處理相關的領域用得非常的多)為了支持向量計算系統了也提供了眾多的向量寄存器.
向量寄存器 128位:V0-V31, 位數最高的寄存器
通用寄存器
通用寄存器也稱數據地址寄存器通常用來做數據計算的臨時存儲嘴脾、做累加男摧、計數、地址保存等功能统阿。定義這些寄存器的作用主要是用于在CPU指令中保存操作數彩倚,在CPU中當做一些常規(guī)變量來使用。
ARM64擁有有32個64位的通用寄存器 x0 到 x30扶平,以及XZR(零寄存器),這些通用寄存器有時也有特定用途帆离。
那么w0 到 w28 這些是32位的. 因為64位CPU可以兼容32位.所以可以只使用64位寄存器的低32位.
比如 w0 就是 x0的低32位!
pc寄存器(program counter)
為指令指針寄存器,它指示了CPU當前要讀取指令的地址
在內存或者磁盤上结澄,指令和數據沒有任何區(qū)別哥谷,都是二進制信息
CPU在工作的時候把有的信息看做指令,有的信息看做數據麻献,為同樣的信息賦予了不同的意義
比如 1110 0000 0000 0011 0000 1000 1010 1010?
可以當做數據 0xE003008AA?
也可以當做指令 mov x0, x8
CPU根據什么將內存中的信息看做指令们妥?
CPU將pc指向的內存單元的內容看做指令
如果內存中的某段內容曾被CPU執(zhí)行過,那么它所在的內存單元必然被pc指向過
高速緩存
iPhoneX上搭載的ARM處理器A11它的1級緩存的容量是64KB勉吻,2級緩存的容量8M.
CPU每執(zhí)行一條指令前都需要從內存中將指令讀取到CPU內并執(zhí)行监婶。而寄存器的運行速度相比內存讀寫要快很多,為了性能,CPU還集成了一個高速緩存存儲區(qū)域.當程序在運行時,先將要執(zhí)行的指令代碼以及數據復制到高速緩存中去(由操作系統完成).CPU直接從高速緩存依次讀取指令來執(zhí)行.
bl指令
CPU從何處執(zhí)行指令是由pc中的內容決定的齿桃,我們可以通過改變pc的內容來控制CPU執(zhí)行目標指令
ARM64提供了一個mov指令(傳送指令)惑惶,可以用來修改大部分寄存器的值,比如
mov x0,#10短纵、mov x1,#20
但是带污,mov指令不能用于設置pc的值,ARM64沒有提供這樣的功能
ARM64提供了另外的指令來修改PC的值香到,這些指令統稱為轉移指令鱼冀,最簡單的是bl指令
例
bl :正在調用方法或函數
棧
SP和FP寄存器
sp寄存器在任意時刻會保存我們棧頂的地址.
fp寄存器也稱為x29寄存器屬于通用寄存器,但是在某些時刻我們利用它保存棧底的地址!
注意:ARM64開始,取消32位的 LDM,STM,PUSH,POP指令! 取而代之的是ldr\ldp str\stp
ARM64里面 對棧的操作是16字節(jié)對齊的!!
關于內存讀寫指令
注意:讀/寫 數據是都是往高地址讀/寫
str(store register)指令
將數據從寄存器中讀出來,存到內存中.
ldr(load register)指令
將數據從內存中讀出來,存到寄存器中
此ldr 和 str 的變種ldp 和 stp 還可以操作2個寄存器.
注: ios 中拉伸棧空間是由高地址到低地址悠就。由低地址到高地址是堆空間千绪。當堆和棧空間想加大于內存空間梗脾,就會發(fā)生堆棧溢出的問題翘紊。 (線程保護,進程保護藐唠,每一個獨立的進程都有自己獨立的內存空間)
內存泄漏是在堆空間中帆疟,一個對象或者一個結構體在堆中要先做free,然后free指針置為nil鹉究,會產生壞地址指針(野指針)
棧空間是高地址向低地址拉伸的踪宠,但是也是先進后出的自赔,那么上面的棧數據怎么釋放呢?
棧是為函數開辟的柳琢,函數調用棧绍妨,棧拉伸,所以不存在提前釋放柬脸。
死循環(huán)和死遞歸有什么區(qū)別他去?
死循環(huán)不一定會崩潰,死遞歸會崩潰倒堕,int a(){? a(); } 內存 stack overflow ,堆棧溢出
//每一次指令只有4個字節(jié)
給程序員操作的寄存器只有x0 ~ x30,
str? ? w0, [sp,#0xc]??
這句話會出問題灾测,因為A中將棧的空間拉伸了32個字節(jié),執(zhí)行完A后回到mian函數垦巴,這時sp指針拿著原來的偏移去找原來函數媳搪,會找不到,就會出現壞地址訪問,所以A操作完后要進行 恢復棧的平衡骤宣,就是把棧內存釋放掉
add? ? sp, sp,#0x20