Swift語法 Swift5 【00 - 匯編】


  • 作者: Liwx
  • 郵箱: 1032282633@qq.com
  • 源碼: 需要源碼的同學, 可以在評論區留下您的郵箱

iOS Swift 語法 底層原理內存管理分析 專題:【iOS Swift5語法】

00 - 匯編
01 - 基礎語法
02 - 流程控制
03 - 函數
04 - 枚舉
05 - 可選項
06 - 結構體和類
07 - 閉包
08 - 屬性
09 - 方法
10 - 下標
11 - 繼承
12 - 初始化器init
13 - 可選項


目錄

  • 01-程序的本質
    • 01-軟件/程序執行過程
  • 02-寄存器和內存
  • 03-編程語言的發展
  • 04-編程語言的發展
  • 05-匯編語言的種類
  • 06-常用匯編指令
  • 07-寄存器
  • 08-寄存器兼容
  • 09-lldb常用指令
  • 10-lldb常用指令(斷點調試)
  • 11-規律

01-程序的本質

Xcode調試中顯示匯編代碼Debug -> Debug Workflow -> Always Show Disassembly


01-軟件/程序執行過程

  • 程序運行時,
    程序/軟件是存儲在硬盤中,當程序開始執行是,從硬盤裝載內存,CPU再對內存進行讀寫,并控制
    ,話筒等其他設備.
  • CPU中包含幾個部分,其中包含寄存器(信息存儲),運算器(信息處理),控制器.

02-寄存器和內存

  • 通常CPU會先將內存中的數據存儲到寄存器中,然后再對寄存器的數據進行運算
  • 假設內存中有塊內存空間1的值是3,現在想將它的值加1,并將結果存儲到內存空間2
  • CPU首先會將內存空間1的值放到rax寄存器中: movq 內存空間1 %rax
  • 然后讓rax寄存器與1相加: addq $0x1 %rax
  • 最后將值賦值給內存空間2: movq %rax 內存空間2

03-編程語言的發展

  • 機器語言
  • 01組成
  • 匯編語言
  • 符號代替了0和1,比機器語言更便于閱讀和記憶
  • 高級語言
  • C/C++/Java/JavaScript/Python等,更接近人類自然語言
  • 操作: 將寄存器BX內容送入寄存器AX
  • 機器語言: 1000100111011000
  • 匯編語言: movw %bx %ax
  • 高級語言: ax = bx

04-編程語言的發展

  • 高級語言 編譯-> 匯編語言 編譯-> 機器語言 運行-> 計算機
  • 反編譯: 機器語言 反編譯-> 匯編語言
  • 匯編語言與機器語言一對應 ,每一條機器指令都有與之對應的匯編指令
  • 匯編語言可以通過編譯得到機器語言機器語言可以通過反匯編得到匯編語言
  • 高級語言可以通過編譯得到匯編語言\機器語言,但匯編語言機器語言幾乎不可能還原成高級語言

05-匯編語言的種類

  • 匯編語言的種類
  • 8086匯編(16bit)
  • x86匯編(32bit)
  • x64匯編(64bit)
  • ARM匯編(嵌入式、移動設備)
  • ......
  • x86、x64匯編根據編譯器的不同,有2種書寫格式
  • Intel: Windows派系
  • AT&T : Unix派系.
  • 作為iOS開發工程師,最主要的匯編語言是
  • AT&T匯編-> iOS模擬器
  • ARM匯編-> iOS真機設備

06-常用匯編指令

注意: 小括號()通常表示存放內存地址。

在AT&T指令中 $立即數的前稱。

項目 AT&T Intel 說明
寄存器名稱 %rax rax
操作數順序 movq %rax, %rdx mov rdx, rax 將rax的值賦值給rdx
常數/立即數 movq $0x3, %rax mov rax, 0x3 將3賦值給rax
內存賦值 movq $0xa, 0x1ff7(%rip) mov qword ptr [rip+0x1ff7], 0xa 將0xa賦值給地址為rip+0x1ff7的內存空間
取內存地址 leaq -0x18(%rbp), %rax lea rax, [rbp-0x18] 將rbp-0x18這個地址值賦值給rax
jmp跳轉指令 jmp *%rdx 或 jmp 0x4001002 或 jmp *(%rax) jmp rdx 或 jmp 0x4001002 或 je=mp [rax] call和jmp寫法類似
操作數長度 movl %eax, %edx 或 movb $0x10, %al 或 leaw 0x10(%dx), %ax mov edx, eax 或 mob al, 0x10 或 lea ax, [dx+0x10] 參考操作數長度說明
  • 操作數長度說明
  • 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常作為函數返回值使用

    • rdi、rsi、rdx、rcx、r8、r9等寄存器常用于存放函數參數
    • rsp、rbp用于棧操作
    • rip作為指令指針
      • 存儲著CPU下一條要執行的指令的地址
      • 一旦CPU讀取一條指令, rip會自動指向下一 條指令(存儲下一條指令的地址)

08-寄存器兼容

為兼容不同位數, 取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進制
  • 字節大小

    • b - byte 1字節
    • h - half word 2字節
    • w - word 4字節
    • g - giant word 8字節
  • 讀取寄存器的值
    • 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  
  • 讀取內存中的值
    • x/數量-格式-字節大小 內存地址
    • x/3gw 0x0000010
(lldb) x/3xg 0x00007fff81c908f8
0x7fff81c908f8: 0x0000000000000200 0x00007fff683e58ec
0x7fff81c90908: 0x0000000000000000
  • 修改內存中的值
    • memory write 內存地址 數值
    • 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常用指令(斷點調試)

  • thread step-over、 next、 n
    • 單步運行,把子函數當做整體-步執行(源碼級別)
  • thread step-in、step、 s
    • 單步運行,遇到子函數會進入子函數(源碼級別)
  • thread step inst over、 nexti、 ni
    • 單步運行,把子函數當做整體-步執行 (匯編級別)
  • thread step-inst、 stepi、 si
    • 單步運行,遇到子函數會進入子函數(匯編級別)
  • thread step-out、 finish
    • 直接執行完當前函數的所有代碼,返回到上一個函數(遇到斷點會卡住)

11-規律

  • 內存地址格式為: 0x4bdc(%rip) ,一般是全局變量 ,全局區(數據段)
  • 內存地址格式為: -0x78(%rbp) , 一般是局部變量,棧空間
  • 內存地址格式為: 0x10(%rax) , 一般是堆空間

iOS Swift 語法 底層原理內存管理分析 專題:【iOS Swift5語法】

下一篇: 01 - 基礎語法


最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
禁止轉載,如需轉載請通過簡信或評論聯系作者。