- 作者: 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-编程语言的发展
- 机器语言
- 由
0
和1
组成 - 汇编语言
- 用
符号
代替了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 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
常作为函数返回值
使用-
rdi、rsi、rdx、rcx、r8、r9
等寄存器常用于存放函数参数
-
rsp、rbp
用于栈操作
-
rip
作为指令指针
- 存储着CPU
下一条要执行的指令
的地址 - 一旦CPU读取一条指令,
rip会自动指向下一 条指令
(存储下一条指令的地址)
- 存储着CPU
-
08-寄存器兼容
为兼容不同位数, 取
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: 低八位
09-lldb常用指令
-
格式
-
x
是16
进制,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 - 基础语法