本人有若干成套学习视频, 可试看! 可试看! 可试看, 重要的事情说三遍 包含Java
, 数据结构与算法
, iOS
, 安卓
, python
, flutter
等等, 如有需要, 联系微信tsaievan
.
(一)程序的本质
让我们来看一副图, 看看程序的本质是什么:
通常, CPU
会先将内存中的数据存储到寄存器中, 然后再对寄存器中的数据进行运算
假设内存中有块红色内存空间的值是3
, 现在想把它的值加1
, 并将结果存储到蓝色内存空间
CPU
首先会将红色内存空间的值放到rax寄存器中:movq 红色内存空间, %rax
然后让rax寄存器与1相加:
addq $0x1, %rax
最后将值赋值给内存空间:
movq %rax, 蓝色内存空间
如下图所示:
(二)编程语言的发展
机器语言
由0
和1
组成汇编语言(
Assembly Language
)
用符号代替了0
和1
, 比机器语言便于阅读和记忆高级语言
C/C++/Java/JS/Python
等, 更接近人类自然语言操作
机器语言:1000100111011000
汇编语言:movw %bx, %ax
高级语言:ax = bx
汇编语言与机器语言一一对应, 每一条机器指令都有与之对应的汇编指令
汇编语言可以通过编译得到机器语言, 机器语言可以通过反汇编得到汇编语言
高级语言可以通过编译得到汇编语言/机器语言, 但汇编语言/机器语言几乎不可能还原成高级语言
(三)汇编语言的种类
汇编语言的种类
8086
汇编(16bit
)
x86
汇编(32bit
)
x64
汇编(64bit
)
ARM
汇编(嵌入式, 移动设备)x86, x64汇编根据编译器的不同, 有2种书写格式
Intel: Windows派系
AT&T: Unix派系作为iOS开发工程师, 最主要的汇编语言是:
AT&T汇编 ->iOS模拟器
ARM汇编 ->iOS真机设备
(四)常见汇编指令
寄存器命名:
AT&T:%rax
Intel:rax
操作数顺序: 将
rax
的值赋值给rdx
AT&T:movq %rax, %rdx
Intel:mov rdx, rax
常数, 立即数: 将
3
赋值给rax
, 将0x10
赋值给rax
AT&T:movq $3, %rax
movq $0x10, %rax
Intel:mov rax, 3
mov rax, 0x10
内存赋值: 将
0xa
赋值给地址为rip+0x1ff7
的内存空间
AT&T:movq $0xa, 0x1ff7(%rip)
Intel:mov qword ptr [rip+0x1ff7], 0xa
取内存地址: 将
rbp-0x18
这个地址赋值给rax
AT&T:leaq -0x18(%rbp), %rax
Intel:lea rax, [rbp - 0x18]
jump
指令:call
和jump
写法类似
AT&T:jump *%rdx
jump 0x4001002
jump *(%rax)
Intel:jmp rdx
jmp 0x4001002
jmp [rax]
操作数长度:
b = byte(8-bit)
s = short(16-bit integer or 32-bit floating point)
w = word(16-bit)
l = long(32-bit integer or 64-bit floating point)
q = quad(64bit)
t = ten bytes(80-bit floating point)
AT&T: movl %eax, %edx
movb $0x10, %al
leaw 0x10(%dx), %ax
Intel: mov edx, eax
mov al, 0x10
lea ax [dx + 0x10]
(五)寄存器
有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
会自动指向下一条指令(存储下一条指令的地址)
(六)lldb
常用指令
读取寄存器的值
register read/格式
register read/x
修改寄存器的值
register write 寄存器名称 数值
register write rax 0
读取内存中的值
x/数量-格式-字节大小 内存地址
x/3xw 0x0000010
修改内存中的值
memory write内存地址 数值
memory write 0x0000010 10
格式
x
是16进制,f
是浮点,d
是十进制字节大小
b -byte
1字节
h -half word
2字节
w -word
4字节
g -giant word
8字节expression 表达式
可以简写:expr 表达式
expression $rax
expression $rax = 1
po 表达式
print 表达式
po/x $rax
po (int) $rax
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
直接执行完当前函数的所有代码, 返回到上一个函数(遇到断点会卡住)
(七)规律
- 内存地址格式为:
0x4bdc(%rip)
, 一般是全局变量, 全局区(数据段) - 内存地址格式为:
-0x78(%rbp)
, 一般是局部变量, 栈空间 - 内存地址格式为:
0x10(%rax)
, 一般是堆空间