要想掌握一门语言,就要探其本质,知晓其中的内存和指针变化,这时候汇编就显得格外重要。
汇编语言的种类
汇编语言的种类
- 8086汇编(16bit)
- x86汇编(32bit)
- x64汇编(64bit)
- ARM汇编(嵌入式,移动设备)
- ……
x86、x64汇编根据编译器的不同,有2种书写格式
- Intel:Windows派系
- AT&T:Unix派系(例,iOS模拟器)
常见汇编指令
寄存器与内存
- CPU组成
- 寄存器(信息存储)
- 运算器(信息处理)
- 控制器
通常,CPU会先将内存中的数据存储到寄存器中,然后再对寄存器中的数据进行运算
假设内存中有块红色内存空间的值是3,现在先把它的值+1,并将结果存储到绿色内存空间
图解:
代码:
1 | var num = 3 |
寄存器
64位AT&T混编中常用的寄存器有16种
- %rax、%rbx、%rcx、%rdx、%rsi、%rdi、%rbp、%rsp
- %r8、%r9、%r10、%r11、%r12、%r13、%r14、%r15
寄存器的具体用途
- %rax常作为函数返回值使用
- %rdi、%rsi、%rdx、%rcx、%r8、%r9等寄存器常用于存放函数参数
- %rsp、%rbp用于栈操作
movq -0x18(%rbp), %rax
意思:根据内存地址找到对应存储空间的数据取出来赋值给%rax
leaq -0x18(%rbp), %rax
意思:直接将%rbp-0x18地址值赋值给%rax
call
和jmp
区别jmp 0x000a1841
,跳转到函数内存地址0x000a1841
执行相关指令,跳转后不返回call 0x000a1841
,也是跳转,和ret
配合使用,但跳转0x000a1841
函数执行完成后会返回继续执行之前的代码
call *%rdx
,意思是跳转到寄存器里面的地址混编指令后面的字符是什么意思?(例:
movq
、leaw
)- 代表操作数长度(具体参照上图)
r
开头的是64位(8字节)的寄存器(CPU是64位的)
e
开头的是32位(4字节)的寄存器(CPU是32位的)
ax
、bx
、cx
开头的是16位(2字节)的寄存器(CPU是16位的)
ah
、al
、bh
、bl
开头的是8位(1字节)的寄存器(CPU是8位的)h
意思是high,代表占用高位;l
意思是low,代表占用低位
思考:高位寄存器怎么兼容低位寄存器?
- 64位寄存器需要兼容32位,32位需要兼容16位
- 如果使用的是64位(63
0),把内存的低位给32位用(310),一直往后推理
lldb常用指令
读取寄存器的值:
register read/格式
register read/x
- 例:
register read rax
- 在lldb中不需要加
%
,在汇编语言中才需要加 - 如果只输入
register read
,就会把所有寄存器的值打印出来
修改寄存器的值
register write 寄存器名称 数值
register write $rax 0
读取内存中的值
x/数量-格式-字节大小 内存地址
x/3xw 0x0000000100008200
意思:读取3组16进制形式展示的数据,每组4个字节
修改内存中的值
memory write 内存地址 数值
memory write 0x0000000100008200 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
expression 高级语言代码
- 可以简写:
po 表达式
print 表达式
po/x $rax
更多指令参考
help expression
示例代码
1 | func test() { |
指令展示
代码调试运行指令
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
- 直接执行完当前函数的所有代码,返回到上一个函数(遇到断点会卡主)
- 简写:
看到上面的指令名称,应该常用Xcode开发的同学会很熟悉,没错,就是Xcode上面的断点调试功能
补充:xorl
- 按位异或
$
- 立即数