1: 基础语法,汇编初探

131 阅读2分钟

一. 课程大纲所示

汇编分析String、Array底层视频 截屏2022-12-23 21.50.41.png

  • 随着ABI的稳定,Swift语法基本不会再有太大变动,此时正是学习Swift的最佳时机
  • Swift完全开源:github.com/apple.swift, 主要采用C++编写

截屏2022-12-27 22.21.33.png

1.1 编译流程

截屏2022-12-23 22.17.00.png

1.2 编译器
  1. 前端: 语法分析...
  2. 后端: 生成对应平台的二进制代码

截屏2022-12-23 22.20.42.png Swift Code: swift 代码

Swift AST: Swift 语法树

Raw Swift IL: Swift 特有的的中间代码

Canonical Swift IL: Swift特有的简洁版中间代码

LLVM IR: LLVM的中间的代码

Assembly: 汇编代码

Executable: 二进制代码

1.3 swiftc
  • swiftc存在在Xcode内部 Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

一些操作: 生成语法树:swiftc -dump-ast main.swift

生成最简洁的SIL代码:swiftc -emit-sil main.swift

生成LLVM IR代码:swiftc -emit-ir main.swift

生成汇编代码:swiftc -emit-assembly main.swift -o main.s

  • 对汇编代码进行分析,可以真正掌握编程语言的本质 如下代码
int c = sizeof(int);  /// 这个 sizeof是函数吗
printf("%d", c)

直接看汇编

截屏2022-12-23 22.49.05.png 你会发现他就是直接将4赋值给了c的寄存器 它就没有触发调用callp,如printf就触发调用了callp

1.4 swift编程入门
  • 不用编写main函数,Swift将全局范围内的首句可执行代码作为程序入口
  • 一句代码尾部可以省略分号(;), 多句代码写到同一行时必须用分号(;)隔开
  • var定义变量,let定义常量,编译器能自动推断出变量/常量的类型
常量
  • 只能赋值1次
  • 它的值不要求在编译时期确定,但使用之前必须赋值1次
var num = 10;
num += 20;
let age = num;

或者

func getAge() -> Int {
    return 30;
}

let age = getAge();

以上两段代码,明明常量age是在运行时确定的,这就是Swift的强大之处,其他语言的话,常量必须是编译时就确定的。

  • 常量,变量在初始化之前,都不能使用

截屏2022-12-23 23.57.24.png

二:常见的数据类型

截屏2022-12-23 23.59.05.png swift分为两种数据类型

  • 值类型
  • 引用类型
2.1 字面量

截屏2022-12-27 22.22.21.png

/// 整数转换
let int1: UInt16 = 2_00;
let int2: UInt8 = 1;
let int3 = int1 + UInt16(int2)
/// 整数,浮点数转换
let int = 3;
let double = 0.14159;
let pi = Double(int) + double
/// 字面量可以直接相加,因为数字字面量本身没有明确的类型
let result = 3 + 0.14159
2.2 元组(tuple)
let http404Error = (404, "NOt Found")
http404Error.0;  /// 404
http404Error.1;  /// "NOt Found"
print("The status code is \(http404Error.0)")

let (statusCode, statusMessage) = http404Error;
print("The status code is \(statusCode)")

let (statusCode, _) = http404Error;

/// 也可以给元组元素命名
let http200Status = (statusCode: 200, description: "OK");
print("The status code is \(http200Status.statusCode)")