CMU CSAPP笔记 第三章
machine language(csapp-3.1~3.5)
- 基本操作
- operand src dest
- 地址表示模式
control(csapp-3.6)
- 条件码
-
testq %rax,%rax
可以检测%rax正负 - 左侧为控制条件转移, 右侧为数据条件转移
- 数据条件转移适合于内部计算不复杂的情况,并且可能带来副作用
- 好处:
-
while循环编译成汇编时,会变成两种goto形式
第一种:jump to middle
第二种: guarded-do
- for循环也会改成while形式在改成goto形式
- init有时可省去
- init有时可省去
- switch编译时会使用jump table结构
- 无须使用if-else结构
- 跳转所花费时间与开关数量无关
- 使用的是ja,处理无符号数,这样可以很方便的处理负数
- 负数映射为无符号时变成大正数
* procedure(csapp-3.7)*
- pop 和 push
-
push %reg
:%rsp 的值减去 8,把寄存器 %reg 中的值放到 (%rsp) 中 -
pop %reg
:把寄存器 (%rsp) 中的值放到 %reg 中,%rsp 的值加上 8
-
- call指令
- 把call代码下一行的地址A压如栈中
- 将PC设为被调用函数的起始位置
- ret指令
- 从栈中弹出地址A
- 将PC设为A
- 寄存器分为调用者寄存器和被调用者寄存器
- 调用者寄存器表示被调用者不可以更改里面的值
- 被调用者寄存器表示调用者可以更改,调用时需要将后面要用到的值保存在调用者的栈帧中
- 调用函数时参数的前六个保存在寄存器中,后边的保存在调用函数的栈帧中
- 参数从底下往上保存
data(csapp-3.8~3.9)
-
32位与64位区别
- 内存不是如上图那样类似一个个长32位或者64位的长方体堆积而成,然后每个长方体一个内存地址的,实际上内存类似一个很长很长的带子
- 内存的访问最小单位为1字节,也就是8个bit
- 所谓64位和32位是指表示一个内存地址所需要的字节
- 因此两者最大的差异就是上一章所说的虚拟地址大小
- 对于32位操作系统,我们最多可以访问的内存大小就是4G,所以即使你拥有一个8G的内存条也是没有用的,因为后面的地址无法表示
二维数组访问
-
对齐
- 任何K字节的基本对象的地址必须为K的倍数
- 在写结构内部的对象时,应该依照从大到小的顺序声明,这样可以减少结构大小
overflow(csapp-3.10~3.10)
- 一个程序的内存示意图
- 栈溢出
- 防止栈溢出攻击的三种方法
- 随机化栈的坐标
- 部分区域不可读
- 认证机制
- 设置一段防护区域,如果被改变,则报告栈溢出