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

一口气看完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: 是否启用内存对齐自动检查

WP: 是否开启内存写保护,若开启,对只读页面尝试写入时将触发异常,这一机制常常被用来实现写时复制功能

PE: 是否开启保护模式

除了CR0,另一个值得关注的寄存器是CR3,它保存了当前进程所使用的虚拟地址空间的页目录地址,可以说是整个虚拟地址翻译中的顶级指挥棒,在进程空间切换的时候,CR3也将同步切换。

调试寄存器

在x86/x64CPU内部,还有一组用于支持软件调试的寄存器。

调试,对于我们程序员是家常便饭,必备技能。但你想过你的程序能够被调试背后的原理吗?

程序能够被调试,关键在于能够被中断执行和恢复执行,被中断的地方就是我们设置的断点。那程序是如何能在遇到断点的时候停下来呢?

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

 

 

对于一些解释执行(PHP、Python、JavaScript)或虚拟机执行(Java)的高级语言,这很容易办到,因为它们的执行都在解释器/虚拟机的掌控之中。

而对于像C、C++这样的“底层”编程语言,程序代码是直接编译成CPU的机器指令来执行的,这就需要CPU来提供对于调试的支持了。

对于通常的断点,也就是程序执行到某个位置下就停下来,这种断点实现的方式,在x86/x64上,是利用了一条软中断指令:int 3来进行实现的。

注意,这里的int不是指高级语言里面的整数,而是表示interrupt中断的意思,是一条汇编指令,int 3则表示中断向量号为3的中断。

在我们使用调试器下断点时,调试器将会把对应位置的原来的指令替换为一个int 3指令,机器码为0xCC。这个动作对我们是透明的,我们在调试器中看到的依然是原来的指令,但实际上内存中已经不是原来的指令了。

顺便提一句,两个0xCC是汉字【烫】的编码,在一些编译器里,会给线程的栈中填充大量的0xCC,如果程序出错的时候,我们经常会看到很多烫烫烫出现,就是这个原因。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zygpfw.html