3.1 历史观点
Inter 处理器俗称x86。
3.2 程序编码
3.2.1 机器级代码
计算机系统使用了多种不同形式的抽象,利用更简单的模型来隐藏实现的细节。
机器级编程:两种抽象尤为重要
- 指令集体系结构或者指令集架构(Instruction Set Architecture,ISA)来定义机器级程序的格式和行为。它定义了处理器状态、指令的格式,以及每条指令对状态的影响。
大多数ISA,包括x86-64,将程序行为描述成每条指令按顺序执行。而实际上,处理器并发地执行许多指令。但可以采取措施使得整体行为和顺序执行一致。 - 机器级程序使用的内存地址是虚拟地址,提供的内存模型看上去是一个非常大的字节数组。
程序计数器(PC,x86-64中用%rip):给出要执行的下一条指令的在内存中的地址。
整数寄存器文件:16个命名的位置,分别存储64位的值。存储地址或者整数数据。有的寄存器用来记录某些重要的程序状态,而其他寄存器保存临时数据,如过程中的参数和局部变量以及函数的返回值。
条件码寄存器:保存最近执行的算术或逻辑指令的状态信息,它们用来控制或数据流的条件变化,如if和while。
一组向量寄存器可以存放一个或多个整数和浮点数值。
3.2.2 代码示例
3.2.3 关于格式的注解
gcc产生的汇编有点难读
3.3 数据格式
字:16位 双字:32位 四字:64位
char * 在32位机器上是4个字节
3.4 访问信息
CPU包含一组16个存储64位值的通用目的寄存器
3.4.1 操作数指令符
三种类型:
立即数,寄存器,内存引用
练习3.1
3.4.2 数据传输指令
3.4.3 数据传输示例
3.4.4 压入和弹出栈元素
栈指针%rsp 保存栈顶元素指针
3.5 算术和逻辑操作
3.5.1 加载有效地址
3.5.2 一元和二元操作符
3.5.3 移位操作
3.5.4 讨论
3.5.5 特殊的算术运算
3.6 控制
3.6.1 条件码
除了整数寄存器,CPU还有一组单个位的条件码寄存器
3.6.2 访问条件码
- 可以根据条件码的某种组合,将1个字节设置为0或1
- 条件跳转到程序的某个其他的部分
- 有条件的传输数据
第一种:指令SET指令
3.6.3 跳转指令
3.6.4 跳转指令的编码
3.6.5 用条件控制来实现条件分支
3.6.5 用条件传送来实现条件分支
条件控制转移:
条件传送:
- 不是所有的条件表达式都可以用条件传送来编译。如果两个表达式中任意一个可能产生错误条件,就会导致非法的行为。
- 也不总是会提高代码的效率。
3.6.7 循环
3.6.8 switch 语句
3.7 过程
3.7.1 运行时栈
3.7.2 转移控制
3.7.3 数据传送
3.7.4 栈上的局部存储
3.7.5 寄存器中的局部存储空间
3.7.6 递归过程
3.8 数组分配和访问
3.8.1 基本原则
3.8.2 指针运算
3.8.3 嵌套的数组
3.8.4 定长数组
3.8.5 变长数组
3.9 异质的数据结构
3.9.1 结构
3.9.2 联合
3.9.3 数据对齐
3.10 在机器级程序中将控制与数据结合起来
3.10.1 理解指针
3.10.2 应用:使用GDB调试器
3.10.3 内存越界引用和缓冲区溢出
3.10.4 对抗缓存区溢出攻击
- 栈随机化
- 栈破坏检测
- 限制可执行代码区域
3.10.5 支持变长栈帧
3.11 浮点代码
3.11.1 浮点传送和转换操作
3.11.2 过程中的浮点代码
3.11 浮点运算操作
3.11.4 定义和使用浮点常数
3.11.5 在浮点代码中使用位级操作
3.11.6 浮点比较操作