大端小端
- 大端 :數(shù)據(jù)存儲(chǔ)如果是大端模式 就和我們?nèi)粘i喿x文章一樣,從做到右,例如 :ff aa bb cc dd ee 88 28 = 0xffaabbccddee8828
- 小端 :iOS存儲(chǔ)模式是小端,所以數(shù)據(jù)要從后向前讀,例如:28 3F 4E 5C = 0X5C4E3F28
寄存器
- 通用寄存器:有32個(gè)寄存器x0-x30和XZR(零寄存器),w0-w30和WZR是兼容32位的,是前面寄存器的低32位;
- x29 : fp寄存器,某些時(shí)刻指向棧底,函數(shù)嵌套時(shí)候才需要
- x30 : lr寄存器,存儲(chǔ)函數(shù)返回后嚇一跳指令地址,一般mov pc x30,把x30的值給到pc寄存器 - sp寄存器 :指向棧頂
- PC寄存器:存儲(chǔ)下一條指令
- 浮點(diǎn)向量寄存器 : 存儲(chǔ)小數(shù)和向量
- 異常狀態(tài)寄存器 :記錄異常狀態(tài)
- 狀態(tài)寄存器CPSR (Current Program Status Register) :
- 32位的,低8位位控制位,程序無法修改,除非CPU運(yùn)行在特權(quán)模式下。
- 最高4位為NZCV,為條件碼標(biāo)志位。
- N (Negative): 是否為負(fù)數(shù),負(fù)數(shù) = 1
- Z (ZERO) : 是否為0,零 = 1
- C (Carry) : 進(jìn)位標(biāo)志,正數(shù)(進(jìn)位 = 1,沒進(jìn)位= 0)負(fù)數(shù)(借位 = 0 ,沒借位 = 1)
- V (Overflow) :溢出標(biāo)志位
- 正數(shù) + 正數(shù) 為負(fù)數(shù) 則溢出
- 負(fù)數(shù) + 負(fù)數(shù) 為正數(shù) 則溢出
- 正數(shù) + 負(fù)數(shù) 不可能溢出
基礎(chǔ)指令
| 指令 | 作用 |
|---|---|
| mov x0 x1 | 把x0的數(shù)據(jù)放入到x1 |
| add x0 #2 x1 | 2 + x1內(nèi)到數(shù)據(jù)存入到x0 |
| ldr x0 sp | 加載內(nèi)存數(shù)據(jù)到寄存器中 |
| str sp x1 | 把sp中的值存入到x1寄存器 |
| adrp x0,1 | 把pc寄存器地址低12位清0,加上一個(gè)便宜值0x fab給到寄存器 |
| bl sp | 跳轉(zhuǎn)到某個(gè)label,并把下一條指令存入lr(x30)寄存器中 |
| b | 無返回值跳轉(zhuǎn) |
| adds | 改變狀態(tài)寄存器nzcv |
| b.ne | 條件跳轉(zhuǎn)eq/ne/lt/gt/lt/gt |
| ret | 返回 |
| cmp | 比較兩個(gè)值一般后面跟b跳轉(zhuǎn)指令,比較的結(jié)果在狀態(tài)寄存器查看,其核心是做減法 |
| ldrsw x8 [ x9, x10, lsl #2] | x10左移2位 + x9的值 給到 x8 |
| lsl/asl | 邏輯/算數(shù)左移 |
| lsr/asr | 邏輯/算數(shù)右移 |
簡(jiǎn)寫
sub sp,sp,#0x10
stp x0,x1,[sp]
stp x0,x1,[sp,#-0x10]! -> sp = sp + #-0x10 -> ++sp用前+
ldr x0,[sp],#0x4 -> sp = sp + #0x4 -> sp++ 用后+
ldr/str 用于正數(shù)
ldur/stur 用于負(fù)數(shù)
ldp/stp 操作兩個(gè)寄存器
函數(shù)
- 葉子函數(shù) :該函數(shù)內(nèi)不再調(diào)用其他函數(shù)
- 非葉子函數(shù) :該函數(shù)內(nèi)調(diào)用了其他函數(shù),要先拉伸棧
- 參數(shù):前8個(gè)參入分別放入到x0-x7寄存器,第9個(gè)以后存入內(nèi)存,在取出
- 返回值: 放入到x0寄存器
Switch
- 超過3個(gè)Case 最好用switch,匯編有可能變成查找表
- Case值最好要連續(xù)的(123456/100,101,102)才會(huì)查找表,否則還是if else
- 表數(shù)據(jù)臨時(shí)放到棧頂
- 最大case值 - 最小case值 如果>0 則在case范圍呢
聲明和定義
.text :代碼段
.global a,b : 定義兩個(gè)全局變量
內(nèi)存分區(qū)
- 代碼區(qū) : 代碼,讀/執(zhí)行
- 棧區(qū) : 參數(shù)、局部變量、臨時(shí)數(shù)據(jù)
- 堆區(qū) :動(dòng)態(tài)申請(qǐng),讀/寫
- 全局變量 :讀/寫
- 常量區(qū) : 讀
- Mach-O :代碼/數(shù)據(jù)(符號(hào)/字符串)/描述信息(Header)
常用命令
//OC文件轉(zhuǎn)匯編
scrub --sdk phones clang -S -arch arm64 main.c -o main.s
//lldb
register read x0 -> 讀取x0寄存器的值
register write pc 0xf123 -> 把值寫入pc寄存器