# 解读《深入理解计算机系统(CSAPP)》第3章程序的机器级表示

本章中,我们了解C语言机器级编程,通过让编译器产生机器级程序的汇编代码表示,了解了编译器和他的优化能力,以及机器、数据类型和指令集。

一、程序编码

gcc命令:C编译器 ;gcc -0g 代表机器代码的优化等级 机器级编程,两种抽象:一、由指令集体系结构或指令集架构来定义机器级程序的格式和行为,它定义了处理器状态、指令的格式、以及每条指令对状态的影响。二、机器级程序使用的内存地址是虚拟地址,提供的内存模型看上去是一个很大的、按字节寻址的数组。

二、数据格式

x86-64指令集包括完整的针对字节、字和双字的指令。

C声明 Intel数据类型 汇编代码后缀 大小(字节)
char 字节 b 1
short 字(短整型) w 2
int 双字(整型) l 4
long 四字(长整型) q 8
char* 四字 q 8
float 单精度 s 4
double 双精度 l 8

三、访问信息

一个x86-64的中央处理器单元(CPU)包含一组16个存储64位值的通用目的寄存器。这些寄存器用来存储整数数据和指针。

指令可以对这16个寄存器的低位字节中存放的不同大小的数据进行操作。生成1字节和2字节数字的指令会保持剩下的字节不变, 生成4字节数字的指令会把高位4个字节置为0(高16位)。

img

四、汇编指令

指令 效果 描述
数据传输指令
mov 传送
pushq 压入栈
popq 弹出栈
leaq 加载有效地址 是movq指令的变形
算术和逻辑操作
INC 加1
DEG 减1
NEG 去负
NOT 取补
ADD
SUB
IMUL
XOR 异或
OR
AND
SAL 左移
SHL 左移
SAR 算术右移
SHR 逻辑右移
imulp 有符号乘法
mulp 无符号乘法
cqto 转换为8字节
idivq 有符号除法
divq 无符号除法
控制
CMP 不修改寄存器的值,只设置条件码 比较
TEST 测试
SET 根据条件码组合set0/1 访问条件码
jump 跳转到另一条带标号的目的地 跳转指令
cmove 用条件传送来实现条件分支
switch_eg 引用跳转表 switch语句
过程
call 控制从函数P转移到函数Q的过程 转移控制
%rdi %edx…… 寄存器中的局部存储变量 数据传送

五、理解指针

1、每个指针都有都有一个值 2、指针用 & 创建 3、* 用于间接引用指针 4、数组引用(a[3])与指针运算和间接引用(*(a+3))有一样的效果 5、将指针从一种类型强制转换成另一种类型,只改变他的类型,不改变他的值 7、指针可以指向函数(int fun(int i); int (*fp)(int i); fp = fun;)

六、小结

我们了解C语言机器级编程,通过让编译器产生机器级程序的汇编代码表示,了解了编译器和他的优化能力,以及机器、数据类型和指令集。

Java的目标代码是特殊的二进制——java字节码,可以看成是虚拟机的机器级程序,软件解释器处理字节代码。另外有一种及时编译(just-in-time compilation JIT)动态的将字节码序列翻译成机器指令。