- 作者: Liwx
- 郵箱: 1032282633@qq.com
- 源碼: 需要
源碼的同學, 可以在評論區(qū)留下您的郵箱
iOS Swift 語法
底層原理與內(nèi)存管理分析 專題:【iOS Swift5語法】00 - 匯編
01 - 基礎語法
02 - 流程控制
03 - 函數(shù)
04 - 枚舉
05 - 可選項
06 - 結構體和類
07 - 閉包
08 - 屬性
09 - 方法
10 - 下標
11 - 繼承
12 - 初始化器init
13 - 可選項
目錄
- 01-程序的本質(zhì)
- 01-軟件/程序執(zhí)行過程
- 02-寄存器和內(nèi)存
- 03-編程語言的發(fā)展
- 04-編程語言的發(fā)展
- 05-匯編語言的種類
- 06-常用匯編指令
- 07-寄存器
- 08-寄存器兼容
- 09-lldb常用指令
- 10-lldb常用指令(斷點調(diào)試)
- 11-規(guī)律
01-程序的本質(zhì)
Xcode調(diào)試中
顯示匯編代碼:Debug -> Debug Workflow -> Always Show Disassembly
01-軟件/程序執(zhí)行過程
- 程序運行時,
程序/軟件是存儲在硬盤中,當程序開始執(zhí)行是,從硬盤裝載到內(nèi)存,CPU再對內(nèi)存進行讀寫,并控制
,話筒等其他設備. - CPU中包含幾個部分,其中包含
寄存器(信息存儲),運算器(信息處理),控制器.
02-寄存器和內(nèi)存
- 通常CPU會先將
內(nèi)存中的數(shù)據(jù)存儲到寄存器中,然后再對寄存器的數(shù)據(jù)進行運算 - 假設內(nèi)存中有塊內(nèi)存空間1的值是3,現(xiàn)在想將它的值加1,并將結果存儲到內(nèi)存空間2
- CPU首先會將內(nèi)存空間1的值放到rax寄存器中:
movq 內(nèi)存空間1 %rax - 然后讓rax寄存器與1相加:
addq $0x1 %rax - 最后將值賦值給內(nèi)存空間2:
movq %rax 內(nèi)存空間2
03-編程語言的發(fā)展
- 機器語言
- 由
0和1組成 - 匯編語言
- 用
符號代替了0和1,比機器語言更便于閱讀和記憶 - 高級語言
- C/C++/Java/JavaScript/Python等,更接近人類自然語言
- 操作: 將寄存器BX內(nèi)容送入寄存器AX
- 機器語言:
1000100111011000 - 匯編語言:
movw %bx %ax - 高級語言:
ax = bx
04-編程語言的發(fā)展
- 高級語言
編譯-> 匯編語言 編譯-> 機器語言 運行-> 計算機 - 反編譯:
機器語言 反編譯-> 匯編語言 - 匯編語言與機器語言一對應 ,每一條機器指令都有與之對應的匯編指令
-
匯編語言可以通過編譯得到機器語言,機器語言可以通過反匯編得到匯編語言 -
高級語言可以通過編譯得到匯編語言\機器語言,但匯編語言機器語言幾乎不可能還原成高級語言
05-匯編語言的種類
- 匯編語言的種類
- 8086匯編(16bit)
- x86匯編(32bit)
- x64匯編(64bit)
- ARM匯編(嵌入式、移動設備)
- ......
-
x86、x64匯編根據(jù)編譯器的不同,有2種書寫格式 -
Intel: Windows派系 -
AT&T: Unix派系. - 作為iOS開發(fā)工程師,最主要的匯編語言是
-
AT&T匯編->iOS模擬器 -
ARM匯編->iOS真機設備
06-常用匯編指令
注意:
小括號()通常表示存放內(nèi)存地址。
在AT&T指令中
$是立即數(shù)的前稱。
| 項目 | AT&T | Intel | 說明 |
|---|---|---|---|
| 寄存器名稱 | %rax | rax | |
| 操作數(shù)順序 | movq %rax, %rdx | mov rdx, rax | 將rax的值賦值給rdx |
| 常數(shù)/立即數(shù) | movq $0x3, %rax | mov rax, 0x3 | 將3賦值給rax |
| 內(nèi)存賦值 | movq $0xa, 0x1ff7(%rip) | mov qword ptr [rip+0x1ff7], 0xa | 將0xa賦值給地址為rip+0x1ff7的內(nèi)存空間 |
| 取內(nèi)存地址 | leaq -0x18(%rbp), %rax | lea rax, [rbp-0x18] | 將rbp-0x18這個地址值賦值給rax |
| jmp跳轉(zhuǎn)指令 | jmp *%rdx 或 jmp 0x4001002 或 jmp *(%rax) | jmp rdx 或 jmp 0x4001002 或 je=mp [rax] | call和jmp寫法類似 |
| 操作數(shù)長度 | movl %eax, %edx 或 movb $0x10, %al 或 leaw 0x10(%dx), %ax | mov edx, eax 或 mob al, 0x10 或 lea ax, [dx+0x10] | 參考操作數(shù)長度說明 |
- 操作數(shù)長度說明
b= byte(8-bit)s= short(16-bit integer or 32-bit floating point)w= word(16-bit)l= long(32-bit integer or 63-bit floating pointq= quad(64-bit))t= ten bytes(80-bit floating point)
07-寄存器
-
有16個常用寄存器
- rax、rbx、 rcx、 rdx、 rsi、 rdi、 rbp、 rsp
- r8、r9、 r10、 r11、r12、 r13、 r14、
r15
-
寄存器的具體用途
-rax、rdx常作為函數(shù)返回值使用-
rdi、rsi、rdx、rcx、r8、r9等寄存器常用于存放函數(shù)參數(shù) -
rsp、rbp用于棧操作 -
rip作為指令指針- 存儲著CPU
下一條要執(zhí)行的指令的地址 - 一旦CPU讀取一條指令,
rip會自動指向下一 條指令(存儲下一條指令的地址)
- 存儲著CPU
-
08-寄存器兼容
為兼容不同位數(shù), 取
64位rax寄存器低32位作為eax寄存器使用,低16位作為ax寄存器使用,ah作為高8位使用,al作為低8位使用
- 寄存器說明
r開頭:64-bite開頭:32-bita, b, c, d開頭:16-bitah, al, bh, bl...l和h結尾:8-bit,h: 高八位,l: 低八位

image.png
09-lldb常用指令
-
格式
-
x是16進制,f是浮點,d是十進制
-
-
字節(jié)大小
-
b- byte 1字節(jié) -
h- half word 2字節(jié) -
w- word 4字節(jié) -
g- giant word 8字節(jié)
-
- 讀取寄存器的值
register read/格式 寄存器名稱register read/x
// 讀取rax寄存器的值
(lldb) register read rax
rax = 0x0000000100709e40
// 讀取rax寄存器的值
(lldb) register read/x rax
rax = 0x0000000100709e40
// 讀取所有寄存器的值
(lldb) register read
General Purpose Registers:
rax = 0x0000000100709e40
rbx = 0x0000000000000000
rcx = 0x00007fff81c908f8 libswiftCore.dylib`type metadata for Swift.Int
rdx = 0x0000000100709e60
rdi = 0x0000000100709e48
rsi = 0x00007fff81c96588 libswiftCore.dylib`type metadata for Any + 8
rbp = 0x00007ffeefbff4d0
rsp = 0x00007ffeefbff4b0
r8 = 0x00000000000005dd
r9 = 0x00000000000005e2
r10 = 0x00000000fffffffc
r11 = 0x0000000000000000
r12 = 0x0000000000000000
r13 = 0x0000000000000000
r14 = 0x0000000000000000
r15 = 0x0000000000000000
rip = 0x0000000100000bd2 00-匯編`_0_匯編.test() -> () + 50 at main.swift:13:14
rflags = 0x0000000000000206
cs = 0x000000000000002b
fs = 0x0000000000000000
gs = 0x0000000000000000
- 讀取內(nèi)存中的值
x/數(shù)量-格式-字節(jié)大小 內(nèi)存地址-
x/3gw0x0000010
(lldb) x/3xg 0x00007fff81c908f8
0x7fff81c908f8: 0x0000000000000200 0x00007fff683e58ec
0x7fff81c90908: 0x0000000000000000
- 修改內(nèi)存中的值
- memory write 內(nèi)存地址 數(shù)值
- memory write 0x0000010 10
lldb) memory write 0x00007fff81c908f8 0x10
(lldb) x/xg 0x00007fff81c908f8
0x7fff81c908f8: 0x0000000000000210
(lldb) memory write 0x00007fff81c908f8 0x20
(lldb) x/xg 0x00007fff81c908f8
0x7fff81c908f8: 0x0000000000000220
-
expression表達式- 可以簡寫:
expr高級語言表達式 - expression $rax // 驗證不通過
- expression $rax = 1 // 驗證不通過
- expr unsigned int $foo = 5
- 可以簡寫:
-
po表達式- print 表達式
- po/x $rax // 驗證不通過
- po (int)$rax // 驗證不通過
10-lldb常用指令(斷點調(diào)試)
- thread step-over、 next、
n- 單步運行,把子函數(shù)當做整體-步執(zhí)行(
源碼級別)
- 單步運行,把子函數(shù)當做整體-步執(zhí)行(
- thread step-in、step、
s- 單步運行,遇到子函數(shù)會進入子函數(shù)(
源碼級別)
- 單步運行,遇到子函數(shù)會進入子函數(shù)(
- thread step inst over、 nexti、
ni- 單步運行,把子函數(shù)當做整體-步執(zhí)行 (
匯編級別)
- 單步運行,把子函數(shù)當做整體-步執(zhí)行 (
- thread step-inst、 stepi、
si- 單步運行,遇到子函數(shù)會進入子函數(shù)(
匯編級別)
- 單步運行,遇到子函數(shù)會進入子函數(shù)(
- thread step-out、
finish-
直接執(zhí)行完當前函數(shù)的所有代碼,返回到上一個函數(shù)(遇到斷點會卡住)
-
11-規(guī)律
- 內(nèi)存地址格式為:
0x4bdc(%rip),一般是全局變量 ,全局區(qū)(數(shù)據(jù)段) - 內(nèi)存地址格式為:
-0x78(%rbp), 一般是局部變量,??臻g - 內(nèi)存地址格式為:
0x10(%rax), 一般是堆空間
iOS Swift 語法
底層原理與內(nèi)存管理分析 專題:【iOS Swift5語法】下一篇: 01 - 基礎語法