到此為止,匯編部分就理解完成了狞谱,其中需要重點掌握的是 函數(shù)
刁赖,因為這與我們?nèi)粘i_發(fā)是息息相關(guān)的。
下面是所有匯編知識的一個匯總,如果不想看前面文章的锦亦,也可以直接查看這里
匯編初識
-
1、匯編概述
使用
助記符代替機器指令
的一種編程語言匯編和機器指令是
一一對應(yīng)
的關(guān)系令境,拿到二進制就可以反匯編由于匯編和CPU的指令集是對應(yīng)的杠园,所以匯編不具備移植性
-
2、總線:是由一堆導(dǎo)線的集合
地址總線
:其寬度決定了尋址能力
數(shù)據(jù)總線
:其寬度決定了CPU數(shù)據(jù)的吞吐量
控制總線
:其寬度決定了CPU對其他器件的控制能力
-
3舔庶、進制
任意進制都是由對應(yīng)個數(shù)的符號組成的抛蚁,符號可以自定義
-
2/8/16是相對完美的進制,他們之間的關(guān)系
3
個二進制 使用一個8進制
標(biāo)識4
個二進制 使用一個16進制
標(biāo)識兩個16進制可以標(biāo)識一個字節(jié)惕橙,即8位
-
數(shù)量單位
- 1024 = 1k瞧甩,1024k = 1M,1024M = 1G
-
容量單位
- 1024 = 1KB弥鹦,1024KB = 1MB肚逸,1024MB = 1GB
-
數(shù)據(jù)的寬度
- 計算機中的數(shù)據(jù)是有寬度的,超過了就會溢出
-
4、
寄存器
:CPU為了性能朦促,自內(nèi)部開辟了一小塊臨時存儲區(qū)域浮點向量寄存器
:用于浮點數(shù)/向量的存儲及運算異常狀態(tài)寄存器
-
通用寄存器
:除了存放數(shù)據(jù)有時也有特殊的用途ARM64
擁有32個64位
的通用寄存器X0-X30
以及XZR
(零寄存器)為了
兼容32位
犬钢,所以arm64位擁有W0-W28
以及WZR 30
個32位寄存器32位寄存器并不是獨立存在的
,例如 W0是X0的低32位
-
PC寄存器
:指令指針寄存器PC寄存器里面的
值
保存的就是CPU接下來需要執(zhí)行的指令地址
改變PC的值可以改變程序的執(zhí)行流程
mov
指令不能更改PC寄存器的值
思灰,需要通過bl跳轉(zhuǎn)
指令來改變PC寄存器的值
函數(shù)本質(zhì)(重點掌握g栌獭!H骶巍4跬恰!)
-
1油湖、棧:是一種具有特殊的訪問方式的存儲空間(后進先出巍扛,Last in First out,
LIFO
)- ARM64里面對
棧的操作
是16字節(jié)對齊
的
- ARM64里面對
-
2乏德、
SP
和FP
寄存器-
SP
寄存器在任意時刻會保存棧頂?shù)牡刂?/code>
-
FP
寄存器也稱為x29
寄存器撤奸,屬于通用寄存器,但是在某些時刻利用它保存棧底的地址
-
-
3喊括、棧的讀寫指令
讀:
ldr
(load register)指令 LDR胧瓜、LDP寫:
str
(store register)指令 STR、STP
-
4郑什、
bl
指令跳轉(zhuǎn)指令:
bl 標(biāo)號
府喳,表示程序執(zhí)行到標(biāo)號處,將下一條指令的地址保存到lr寄存器B
代表著跳轉(zhuǎn)
L
表示lr
(x30)寄存ios_reverse_02器
-
5蘑拯、
ret
指令- 類似函數(shù)的
return
- 讓CPU執(zhí)行l(wèi)r寄存器所指向的指令
- 類似函數(shù)的
6钝满、避免嵌套函數(shù)無法回去:需要保護bl(即
lr
寄存器,存放回家的路)申窘,保存在當(dāng)前函數(shù)自己的椡溲粒空間-
7、函數(shù)參數(shù)
arm64中剃法,參數(shù)是放在
x0-x7
的8個寄存器中如果是浮點數(shù)碎捺,就會用浮點數(shù)寄存器
如果
超過8個
參數(shù)就會用棧傳遞
-
8、函數(shù)返回值
一般函數(shù)的返回值使用
x0寄存器
保存如果返回值
大于了8個字節(jié)
(x0寄存器大小是8個字節(jié))玄窝,就會利用內(nèi)存?zhèn)鬟f
返回值
-
9牵寺、函數(shù)局部變量
-
局部變量
存儲在棧
空間
-
10悍引、函數(shù)的嵌套調(diào)用:會將
x29恩脂、x30
寄存器入棧保護-
11、狀態(tài)(標(biāo)志)寄存器 - CPSR
arm64中
cpsr
寄存器(32位
)為狀態(tài)寄存器-
最高4位(28趣斤、29俩块、30、31)為標(biāo)志位
-
N
標(biāo)志(負(fù)標(biāo)記位)執(zhí)行結(jié)果為
負(fù)數(shù)N=1
執(zhí)行結(jié)果
非負(fù)數(shù)N=0
-
Z
標(biāo)志(0標(biāo)記位)結(jié)果
為0則Z=1
結(jié)果
非0則Z=0
-
C
標(biāo)志(無符號溢出)加法:
進位 C=1,否則C=0
減法:
借位 C=0玉凯,否則C=1
-
V
標(biāo)志(有符號溢出)正數(shù)+正數(shù)=
負(fù)數(shù)势腮,則V=1
正數(shù)+負(fù)數(shù)=
正數(shù),則V=0
-
循環(huán)選擇指令(需要多實際操作)
1漫仆、全局變量和常量
獲取
全局變量和常量
時捎拯,會出現(xiàn)adrp
和add
兩條指令獲得一個地址的情況-
ADRP(Address Page)
-
adrp x0,1
將
PC
寄存器的低12位清零
將1的值盲厌,左移12位
以上兩個結(jié)果相加放入
x0
寄存器
-
通過
ADD
指令獲取這頁內(nèi)存中的偏移值
2署照、條件判斷
-
CMP
把一個寄存器的內(nèi)容和另一個寄存器的內(nèi)容或立即數(shù)進行比較,但不存儲結(jié)果吗浩,只是正確的更改標(biāo)志
(CMP后面跟的是B.LE
建芙,即else的條件) - 一般CMP做完判斷后會進行跳轉(zhuǎn),后面通常會跟上B指令
BL 標(biāo)號
:跳轉(zhuǎn)到標(biāo)號處執(zhí)行B.LT 標(biāo)號
:比較結(jié)果是小于(less than )懂扼,執(zhí)行標(biāo)號禁荸,否則不跳轉(zhuǎn)B.LE 標(biāo)號
:比較結(jié)果是小于等于(less than or equal to),執(zhí)行標(biāo)號阀湿,否則不跳轉(zhuǎn)B.GT 標(biāo)號
:比較結(jié)果是大于(greater than)赶熟,執(zhí)行標(biāo)號
,否則不跳轉(zhuǎn)B.GE 標(biāo)號
:比較結(jié)果是大于等于
(greater than or equal to)陷嘴,執(zhí)行標(biāo)號钧大,否則不跳轉(zhuǎn)B.EQ 標(biāo)號
:比較結(jié)果是等于
,執(zhí)行標(biāo)號罩旋,否則不跳轉(zhuǎn)B.NE 標(biāo)號
:比較結(jié)果是不等于(not equal),執(zhí)行標(biāo)號啊央,否則不跳轉(zhuǎn)B.HI 標(biāo)號
:比較結(jié)果是無符號大于
,執(zhí)行標(biāo)號涨醋,否則不跳轉(zhuǎn)B.HS 標(biāo)號
:比較結(jié)果是無符號大于等于
瓜饥,執(zhí)行標(biāo)號,否則不跳轉(zhuǎn)
3浴骂、循環(huán)
do-while
循環(huán):判斷條件在后面
乓土,滿足條件往外跳for
循環(huán)和while
循環(huán)很像:判斷條件在里面
,不滿足就往外跳
4溯警、switch
1趣苏、假設(shè)
switch
語句的分支比較少時(例如3,少于4的時候沒有意義)梯轻,沒有必要使用次結(jié)構(gòu)食磕,相當(dāng)于if-else
2、各個分支常量的
差值較大
時喳挑,編譯器會在效率還是內(nèi)存進行取舍彬伦,這時編譯器還是會編譯成類似于if-else
的結(jié)構(gòu)3滔悉、在
分支比較多
的時候,在編譯的時候會生成一個表
(跳轉(zhuǎn)表每個地址四個字節(jié))单绑。
OC反匯編(需要多實際操作)
-
1回官、編譯器優(yōu)化:
1、設(shè)置:
BuildSetting->Optimization Level
2搂橙、優(yōu)化原則:對結(jié)果沒有任何影響的代碼會被編譯器優(yōu)化
3歉提、編譯器優(yōu)化,本質(zhì)是LLVM的優(yōu)化過程区转,實際上優(yōu)化的是匯編代碼(可以理解為
匯編指令會減少
)
-
2唯袄、指針:
1、指針的
自增自減
和指向的數(shù)據(jù)類型寬度
有關(guān)蜗帜,是按照指向的數(shù)據(jù)類型來運算的(即指針的寬度 - 步長
)2恋拷、指針的
運算單位
是指向的數(shù)據(jù)類型的寬度
3、指針可以通過
if-else
比大小厅缺,因為類型是可以相互轉(zhuǎn)換的
-
3蔬顾、[[self alloc] init] 優(yōu)化過程
在最初的版本(iOS9)中,相當(dāng)于兩次消息發(fā)送
objc_msgSend
iOS11版本 是一次消息發(fā)送
objc_alloc + objc_msgSend
iOS13.5.1以上版本湘捎,已經(jīng)沒有objc_msgSend诀豁,而是
objc_alloc_init
-
4、反匯編分析方式:
通過
LLDB
動態(tài)調(diào)試通過
Hopper + MachOView
靜態(tài)分析