Swift5.0边学边记

Swift5.0边学边记

swiftc

  • 存放路径

      Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
      
    
  • 操作

    生成语法树

    1
    $ swiftc -dump-ast main.swift

    生成最简洁的SIL代码

    1
    swiftc -emit-sil main.swift

    生成LLVM IR代码

    1
    $ swiftc -emit-ir main.swift

    生成汇编代码

    1
    $ swiftc -emit-assembly main.swift -o main.s

汇编

寄存器

AT&T

  • 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会自动指向下一条指令

ARM64

寄存器
  • ARM64 有34个寄存器,包括31个通用寄存器、SP、PC、CPSR

    寄存器 位数 描述
    x0-x30 64bit 通用寄存器,如果有需要可以当做32bit使用:wO-w30
    FP(x29) 64bit 保存栈帧地址(栈底指针)
    LR(x30) 64bit 通常称X30为程序链接寄存器,保存子程序结束后需要执行的下一条指令
    SP 64bit 保存栈指针,使用 SP/WSP 来进行对 SP 寄存器的访问
    PC 64bit 程序计数器,俗称PC指针,总是指向即将要执行的下一条指令,在arm64中,软件是不能改写PC寄存器的
    CPSR 64bit 状态寄存器
  • 用途

    x0 - x7: 用于子程序调用时的参数传递,x0还用于返回值传递,当使用 r0 - r30 访问时,它就是一个64位的数。当使用 w0 - w30 访问时,访问的是这些寄存器的低32位

  • 指令

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    MOV    X1,X0         ;将寄存器X0的值传送到寄存器X1
    ADD X0,X1,X2 ;寄存器X1和X2的值相加后传送到X0
    SUB X0,X1,X2 ;寄存器X1和X2的值相减后传送到X0
    AND X0,X0,#0xF ; X0的值与0xF相位与后的值传送到X0
    ORR X0,X0,#9 ; X0的值与9相位或后的值传送到X0
    EOR X0,X0,#0xF ; X0的值与0xF相异或后的值传送到X0
    LDR X5,[X6,#0x08] ;X6寄存器加0x08的和的地址值内的数据传送到X5
    STR X0, [SP, #0x8] ;X0寄存器的数据传送到SP+0x8地址值指向的存储空间
    STP x29, x30, [sp, #0x10] ;入栈指令
    LDP x29, x30, [sp, #0x10] ;出栈指令
    CBZ ;比较(Compare),如果结果为零(Zero)就转移(只能跳到后面的指令)
    CBNZ ;比较,如果结果非零(Non Zero)就转移(只能跳到后面的指令)
    CMP ;比较指令,相当于SUBS,影响程序状态寄存器CPSR
    B/BL ;绝对跳转#imm, 返回地址保存到LR(X30)
    RET ;子程序返回指令,返回地址默认保存在LR(X30)

lldb常用指令

  • 读取寄存器的值

    1
    2
    3
    $ register read/格式
    exp:
    $ register read/x
  • 修改寄存器的值

    1
    2
    3
    $ register write 寄存器名称 数值
    exp:
    $ register write rax 0
  • 读取内存中的值

    1
    2
    3
    $ x/数量-格式-字节大小 内存地址
    exp:
    $ x/3xw 0x0000010
  • 修改内存中的值

    1
    2
    3
    $ memory write 内存地址 数值
    exp:
    $ memory write 0x0000010 10
  • 格式

    1
    2
    3
    x 是16进制
    f 是浮点
    d 是十进制
  • 字节大小

    1
    2
    3
    4
    b - byte 1字节
    h - half word 2字节
    w - word 4字节
    g - giant word 8字节
  • 规律

    内存地址格式为: 0x4bdc(%rip), 一般是全局变量, 全局区(数据段)

    内存地址格式为: -0x78(%rbp), 一般是局部变量,栈空间

    内存地址格式为: 0x10(%rax), 一般是堆空间

  • 查看调用栈

    bt

基础语法

  • 双重可选

    1
    2
    var num : Int?? = nil
    print(num ?? 10)

    输出结果:

    1
    Optional(10)  // 为什么还会输出一个可选的10

    在Swift源码中是这样描述的

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    ///   - defaultValue: A value to use as a default. `defaultValue` is the same
    /// type as the `Wrapped` type of `optional`.

    public func ?? <T>(optional: T?, defaultValue: @autoclosure () throws -> T)
    rethrows -> T {
    switch optional {
    case .some(let value):
    return value
    case .none:
    return try defaultValue()
    }
    }

流程控制

top