Swift語法 Swift5 【00 - 匯編】


  • 作者: 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ā)展

  • 機器語言
  • 01組成
  • 匯編語言
  • 符號代替了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 point
  • q = 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會自動指向下一 條指令(存儲下一條指令的地址)

08-寄存器兼容

為兼容不同位數(shù), 取64位rax寄存器低32位作為eax寄存器使用,低16位作為ax寄存器使用,ah作為高8位使用,al作為低8位使用

  • 寄存器說明
  • r開頭: 64-bit
  • e開頭: 32-bit
  • a, b, c, d開頭:16-bit
  • ah, al, bh, bl ... l和h結尾8-bit,h: 高八位,l: 低八位
image.png

09-lldb常用指令

  • 格式

    • x16進制,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/3gw 0x0000010
(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í)行(源碼級別)
  • thread step-in、step、 s
    • 單步運行,遇到子函數(shù)會進入子函數(shù)(源碼級別)
  • thread step inst over、 nexti、 ni
    • 單步運行,把子函數(shù)當做整體-步執(zhí)行 (匯編級別)
  • thread step-inst、 stepi、 si
    • 單步運行,遇到子函數(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 - 基礎語法


最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者。

友情鏈接更多精彩內(nèi)容