CSAPP 第三章 笔记

发布时间 2023-11-27 14:22:56作者: dddon

历史观点

程序编码

机器级代码

  • x86-64 可见的处理器状态:
    1. 程序计数器PC:%rip,给出下一条指令的地址
    2. 寄存器文件:16个,储存64位的值
    3. 条形码寄存器:保存最近执行的算术或逻辑指令的状态信息,用来控制条件变化
    4. 向量寄存器:存放多个整数或浮点数值
  • 函数调用保存策略
    1. 调用者保存

    2. 被调用者保存

数据格式

访问信息

操作数

  1. 立即数
    • $-577, $0x1F
  2. 寄存器
  3. 内存引用
    • 最常用:

数据传送指令

  1. 两个操作数不能都指向内存位置
  2. mov指令后缀与寄存器大小匹配
  3. movq指令只能以表示为32位补码数字的立即数作为源操作数,然后把这个值符号扩展得到64位的值,放到目的位置。
  4. movabsq指令能够以任意64位立即数值作为源操作数,并且只能以寄存器作为目的。
  5. 任何位寄存器生成32位值的指令都会把该寄存器的高位部分置为0
  6. 两操作数大小不一
    1. \(movz\)指令:零扩展
      • 最后两个字符为大小指示符
    2. \(movs\)指令:符号扩展
      • 最后两个字符为大小指示符
      • \(cltq\) 等效于 \(movslq \quad\%eax,\%rax\)

压入和弹出栈数据

  • pushq %rbp
  • popq %rax

算术和逻辑操作

加载有效地址leaq

  1. 有效地址计算方式与内存地址计算方式一致

  2. 可以做简单的加法与乘法运算

一元操作(第二组)

一个操作数:寄存器或内存位置

二元操作(第三组)

  • 第一个数:源操作数
    立即数,寄存器或内存位置
  • 第二个数:目的操作数
    寄存器或内存位置

移位操作(第四组)

  • 移位量
    • 立即数,或寄存器cl
    • 移位量由cl\(m\)位决定,其中\(2^m = w\)\(w\)为数据值位长

特殊的算数操作

控制

条件码

  • 条件码的设置
    • 下图中操作都会设置条件码
    • cmptest指令
      • suband类似
      • 不改变寄存器的值
  • 条件码的使用
    1. SET指令根据条件码的某种组合,将一个字节设置为0或者1。
    2. jump指令可以条件跳转到程序的某个其他的部分。
      • 编码
        1. PC相对寻址

          其中第二行:0x8 = 0x5(下一行地址) + 03(跳转指令的目标编码)
          同理 第五行:0x5 = 0xd + f8
    3. 可以有条件地传送数据。
      • 基于条件传送的代码比基于跳转指令的代码效率高
        预测:错误则浪费时间

循环

用条件测试和跳转组合起来实现循环的效果。

  • for, do-while, while
  • switch

    跳转表为数组,重复的情况使用相同标号,缺少的情况使用默认值

过程

传递控制,传递数据,分配和释放内存

运行时栈

  • 栈帧,通过栈指针%rsp维护

转移控制

数据传送

  • 寄存器(6个)

    • 传递参数时,所有数据大小都向8的倍数对齐

栈上的局部存储


局部变量不需要对齐

寄存器中的局部存储空间

  • 统一的使用惯例
    • 调用者保存寄存器
    • 被调用者保存寄存器
  • 栈保存寄存器数值
    入栈保存,出栈恢复

递归过程

数组分配与访问

  • 基本原则
    • 地址计算
  • 指针运算
  • 定长数组,变长数组

异质的数据结构

  • 结构
    • 对齐(插入间隙)
  • 联合
    • 共用空间

控制与数据结合

  • 指针
  • 缓冲区溢出
    • C对数组引用不进行边界检查:破坏栈中状态信息(gets函数)
    • 防御
      • 栈随机化
      • 栈破坏检测(金丝雀值)
      • 限制可执行代码区域
  • 变长栈帧