一口气看完45个寄存器,CPU核心技术大揭秘( 二 )


TF 跟踪标志
IF 中断标志
······
一口气看完45个寄存器,CPU核心技术大揭秘文章插图
在x64架构下 , 原来的eflags寄存器升级为64位的rflags , 不过其高32位并没有新增什么功能 , 保留为将来使用 。
指令寄存器eip: 指令寄存器可以说是CPU中最最重要的寄存器了 , 它指向了下一条要执行的指令所存放的地址 , CPU的工作其实就是不断取出它指向的指令 , 然后执行这条指令 , 同时指令寄存器继续指向下面一条指令 , 如此不断重复 , 这就是CPU工作的基本日常 。
而在漏洞攻击中 , 黑客想尽办法费尽心机都想要修改指令寄存器的地址 , 从而能够执行恶意代码 。
同样的 , 在x64架构下 , 32位的eip升级为64位的rip寄存器 。
段寄存器段寄存器与CPU的内存寻址技术紧密相关 。
早在16位的8086CPU时代 , 内存资源宝贵 , CPU使用分段式内存寻址技术:
一口气看完45个寄存器,CPU核心技术大揭秘文章插图
16位的寄存器能寻址的范围是64KB , 通过引入段的概念 , 将内存空间划分为不同的区域:分段 , 通过段基址+段内偏移段方式来寻址 。
这样一来 , 段的基地址保存在哪里呢?8086CPU专门设置了几个段寄存器用来保存段的基地址 , 这就是段寄存器段的由来 。
段寄存器也是16位的 。
段寄存器有下面6个 , 前面4个是早期16位模式就引入了 , 到了32位时代 , 又新增了fs和gs两个段寄存器 。
cs: 代码段
ds: 数据段
ss: 栈段
es: 扩展段
fs: 数据段
gs: 数据段
段寄存器里面存储的内容与CPU当前工作的内存寻址模式紧密相关 。
当CPU处于16位实地址模式下时 , 段寄存器存储段的基地址 , 寻址时 , 将段寄存器内容左移4位(乘以16)得到段基地址+段内偏移得到最终的地址 。
当CPU工作于保护模式下 , 段寄存器存储的内容不再是段基址了 , 此时的段寄存器中存放的是段选择子 , 用来指示当前这个段寄存器“指向”的是哪个分段 。
注意我这里的指向打了引号 , 段寄存器中存储的并不是内存段的直接地址 , 而是段选择子 , 它的结构如下:
一口气看完45个寄存器,CPU核心技术大揭秘文章插图
16个bit长度的段寄存器内容划分了三个字段:
PRL: 特权请求级 , 就是我们常说的ring0-ring3四个特权级 。
TI: 0表示用的是全局描述符表GDT , 1表示使用的是局部描述符表LDT 。
Index: 这是一个表格中表项的索引值 , 这个表格叫内存描述符表 , 它的每一个表项都描述了一个内存分段 。
这里提到了两个表 , 全局描述符表GDT和局部描述符表LDT , 关于这两个表的介绍 , 下面介绍描述符寄存器时再详述 , 这里只需要知道 , 这是CPU支持分段式内存管理需要的表格 , 放在内存中 , 表格中的每一项都是一个描述符 , 记录了一个内存分段的信息 。
保护模式下的段寄存器和段描述符到最后的内存分段 , 通过下图的方式联系在一起:
一口气看完45个寄存器,CPU核心技术大揭秘文章插图
通用寄存器、段寄存器、标志寄存器、指令寄存器 , 这四组寄存器共同构成了一个基本的指令执行环境 , 一个线程的上下文也基本上就是这些寄存器 , 在执行线程切换的时候 , 就是修改它们的内容 。
一口气看完45个寄存器,CPU核心技术大揭秘文章插图
控制寄存器控制寄存器是CPU中一组相当重要的寄存器 , 我们知道eflags寄存器记录了当前运行线程的一系列关键信息 。
那CPU运行过程中自身的一些关键信息保存在哪里呢?答案是控制寄存器!
一口气看完45个寄存器,CPU核心技术大揭秘文章插图
32位CPU总共有cr0-cr4共5个控制寄存器 , 64位增加了cr8 。 他们各自有不同的功能 , 但都存储了CPU工作时的重要信息:
cr0: 存储了CPU控制标记和工作状态
cr1: 保留未使用
cr2: 页错误出现时保存导致出错的地址
cr3: 存储了当前进程的虚拟地址空间的重要信息——页目录地址
cr4: 也存储了CPU工作相关以及当前人任务的一些信息
cr8: 64位新增扩展使用
其中 , CR0尤其重要 , 它包含了太多重要的CPU信息 , 值得单独关注一下:
一口气看完45个寄存器,CPU核心技术大揭秘文章插图
一些重要的标记位含义如下:
PG: 是否启用内存分页
AM: 是否启用内存对齐自动检查