目录
1、高级程序代码转为机器代码
预处理:在高级语言源程序中插入所有用#include命令指定的文件和用#define声明指定的宏。
编译:将预处理后的源程序文件编译生成相应的汇编语言程序。
汇编:由汇编程序将汇编语言源程序文件转换为可重定位的机器语言目标代码文件。
链接:由链接器将多个可重定位的机器语言目标文件以及库例程(如printf()库函数)链接起来,生成最终的可执行目标文件。
2、GCC使用
编译过程各步骤的对应指令如下:
反汇编可以对a.out(完整的可执行文件)或.o文件进行,目标文件可用“objdump -d test.o” 或“objdump -d test”反汇编为汇编语言程序:
3、汇编器和链接器
汇编器:
- 将.s文件转换为.o文件
- 得到每条指令的二进制编码
- 几乎完整的可执行代码映像
- 不同文件中的代码之间缺少联系
链接器:
- 解析文件之间的引用
- 与静态运行库相结合,例如malloc, printf
- 一些库是动态链接的,当程序开始执行时发生链接。
4、X86-64整数寄存器
一个x86-64的CPU包含一组16个存储64位值得通用目的寄存器,如下:
规则:
- 16位操作可以访问最低2个字节,32位操作访问4个字节,64位操作访问整个寄存器
- 生成1字节和2字节数字的指令会保持剩下的字节不变
- 生成4字节数字的指令会把高位4个字节置为0
5、内存寻址模式
最一般的形式:D(Rb,Ri,S) ,即Mem[ Reg[ Rb ]+S*Reg[ Ri ]+ D ]
含义:
Reg[x]=寄存器x中存放的值,Mem[y]=地址y对应的内存空间
D: 常量“位移”1, 2,或4字节。
Rb: 基址寄存器:16个整数寄存器中的任意一个
Ri: 任何寄存器,除%rsp
S: 规模: 1, 2, 4, or 8(必须注意)
特殊形式:
-
(Rb,Ri) ,即 Mem[Reg[Rb]+Reg[Ri]]
-
D(Rb,Ri) ,即 Mem[Reg[Rb]+Reg[Ri]+D]
-
(Rb,Ri,S),即 Mem[Reg[Rb]+S*Reg[Ri]]
实例
假设%rdx寄存器中存放的值为0xf000,%rcx寄存器中存放的值为0x0100,有以下例子:
式子:0x8(%rdx)
计算:0xf000+0x8
地址:0xf008
式子:(%rdx,%rcx)
计算:0xf000+0x100
地址:0xf100
式子:(%rdx,%rcx,4)
计算:0xf000+4*0x100
地址:0xf400
式子:0x80(,%rdx,2)
计算:2*0xf000 + 0x80
地址:0x1e080
6、数据传送指令:mov
作用:将数据从一个位置复制到另一个位置
形式:mov 源, 目的
movq和movabsq的区别:
movq :传送四字 (只能以32位补码立即数作为操作数,将其符号拓展得到64位放到目的位置)
movabsq I,R 传送绝对的四字 (立即数能以任意64位补码为操作数)
操作数类型
- 立即数: 整型常量,例子: $0x400, $-533
- 寄存器: 16个整数寄存器中的任一个,例子: %rax, %r13
- 内存: 寄存器中给出地址的8个连续字节内存 ,最简单的例子: (%rax)
组合形式
以movq为例: