接着上一篇的汇编总结(一)往下写,本人作为汇编初学者,可能很多方面都有不足之处,希望大家多多包涵,多多交流,谢谢!
1.首先设置一直显示汇编
2.call: 后面跟函数地址(同jmp)
3.lea: 地址传递指令 如上图
4.mov:移动赋值操作,值传递
5.存放函数返回值的寄存器:rax、rdx;
存放函数参数的寄存器:rdi、rsi、rdx、rcx、r8、r9等;
6.(%rdi):rdi放的是地址,去寻找地址所在的存储空间
7.查看变量的内存:
8.枚举变量不同于一般的变量,不能直接看到内存存储的内容,需要借助老师写的工具:
print(Mems.ptr(ofVal: &变量名))//打印变量的地址
打印出内存地址—view Memory of t---输入地址,如下
9.打印变量地址、存储内容
比如:声明一个Int变量是传入10
/*
“小端模式” 真正读出来的是从右向左
0A 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
*/
print(Mems.ptr(ofVal: &TT))//打印变量的地址
------------------------------------------------
/*
cpu读出来如下 高字节---低字节 “高高低低”
0x000000000000000a 0x0000000000000000
*/
print(Mems.memStr(ofVal: &TT))//打印变量地址里的存储内容
10.要点总结:
1》寄存器:
r开头:64bit,8个字节
e开头:32bit,4个字节
ax, bx, cx: 16位 2字节
ah, al: 8bit 1字节
bh, bl:
2》操作数长度:
movq 8个字节 、movl、movb、
3》rip、rbp:
根据内存格式判断局部变量还是全局变量?:
0x712(%rip), %rax 全局变量 程序一启动就分配内存,运行过程中 内存只有一份内存,不会变
-0x18(%rbp), %rax 局部变量 每次分配的都不一样
4》汇编常识:
看到alloc 、malloc就是在申请堆空间
看到call 下的rax 或许是返回的堆空间地址
xorl:异或 同同是0 不同是1
$0x14=20 立即数 简称imm
5》rip:存储的是指令的地址,cpu要执行的下一条指令地址就存在rip中
6》jmp和call
jmp +地址 只负责跳转到某个地址去执行
jmp 后可跟寄存器 间接跳转
call +函数地址 跳到这个地址去执行代码 ret配合使用回到当初call下一句的地方
call *%rax 函数地址在寄存器rax里面
看到call 下的rax 或许是返回的堆空间地址
11.lldb常用指令:
1》读取寄存器的值: register read
比如register read rax
修改寄存器的值: register write 寄存器的名称 数值
比如 register write rax 10
2》读取内存中的值: 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
3》调试汇编:ni、 si同样都是单步执行
ni(把函数当成一个整体执行不进去)、
si(遇到函数也会进去)
调试源码:n、s(同上,只是用于高级语言)
finish:直接执行完当前函数的所有代码,遇到断点也会卡住
注意:在项目执行之前吧汇编里的断点都去掉