本文主要是介绍应知应会的硬核知识--寄存器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
众所周知,寄存器是CPU内部用来存放数据的一些小型存储区域,可用来暂时存放参与运算的数据和运算结果,可分为通用寄存器、专用寄存器和控制寄存器。除此之外,CPU 内部还有运算器
,负责处理数据;控制器
控制其他组件;外部总线
连接 CPU 和各种部件,进行数据传输;内部总线
负责 CPU 内部各种组件的数据处理。
CPU 的主要职责就是用来处理数据,会涉及从存储区域读写数据,内存的数据处理和分配是有开销的,而寄存器拥有非常高的读写速度,所以在寄存器之间的数据传送非常快,所以寄存器通常作为最高速缓存。而在利用汇编做一些inline-hook等黑科技的时候,最主要关注的是寄存器的状态和存储数据。
初识寄存器
我们先简单看下CPU内部的构造:
上图是冯·诺伊曼型计算机的 CPU,每个CPU都有一套自己可以执行的专门的指令集(注意,这部分指令是CPU提供的,CPU-Z软件可查看)。
取指、解码、执行三个过程构成一个CPU的基本周期,称作指令周期(可能还有结果回写)
-
取指令
阶段是将内存中的指令读取到 CPU 中寄存器的过程,程序寄存器用于存储下一条指令所在的地址 -
指令译码
阶段,在取指令完成后,立马进入指令译码阶段,在指令译码阶段,指令译码器按照预定的指令格式,对取回的指令进行拆分和解释,识别区分出不同的指令类别以及各种获取操作数的方法。 -
执行指令
阶段,译码完成后,就需要执行这一条指令了,此阶段的任务是完成指令所规定的各种操作,具体实现指令的功能。 -
结果写回
阶段,作为最后一个阶段,结果写回(Write Back,WB)阶段把执行指令阶段的运行结果数据写回到 CPU 的内部寄存器中,以便被后续的指令快速地存取;
为了改善性能,CPU已经不是单条取指-->解码-->执行
的路线,而是分别为这3个过程分别提供独立的取值单元,解码单元以及执行单元。这样就形成了流水线模式。
CPU内部不可或缺的存储单元寄存器,寄存器按功能一般可划分为通用寄存器、控制寄存器、段寄存器。
通用寄存器
通用寄存器组包括AX、BX、CX、DX4个16位寄存器,用以存放16位数据或地址。
-
AX(Accumulator Register)
:累加寄存器,它主要用于输入/输出和大规模的指令运算。 -
BX(Base Register)
:基址寄存器,用来存储基础访问地址 -
CX(Count Register)
:计数寄存器,CX 寄存器在迭代的操作中会循环计数 -
DX(data Register)
:数据寄存器,它也用于输入/输出操作。它还与 AX 寄存器以及 DX 一起使用,用于涉及大数值的乘法和除法运算。
这四种寄存器可以分为上半部分和下半部分,用作八个 8 位数据寄存器
-
「AX 寄存器可以分为两个独立的 8 位的 AH 和 AL 寄存器;」
-
「BX 寄存器可以分为两个独立的 8 位的 BH 和 BL 寄存器;」
-
「CX 寄存器可以分为两个独立的 8 位的 CH 和 CL 寄存器;」
-
「DX 寄存器可以分为两个独立的 8 位的 DH 和 DL 寄存器;」
寄存器的存储方式是先存储低位,如果低位满足不了就存储高位,如果低位能够满足,高位用 0 补全,在其他低位能满足的情况下,其余位也用 0 补全。
比如数据 14 ,它在 16 位存储器中所存储的表示如下
AX 寄存器
AX 被称作累加寄存器或者简称为累加器,其可以分为 2 个独立的 8 位寄存器 AH 和 AL;在编写汇编程序中,AX 寄存器可以说是使用频率最高的寄存器。
mov ax,10 /* 将 10 送入寄存器 AX*/
mov ah,10 /* 将 10 送入寄存器 AH*/
add ax,10 /* 将寄存器 AX 中的数值加上 10 */
BX 寄存器
BX 被称为基址寄存器,可间接寻址的地址寄存器和基地址寄存器。同样为了适应以前的 8 位 CPU ,而可以将 BX 当做两个独立的 8 位寄存器使用,即有 BH 和 BL,作通用数据寄存器。BX 寄存器中存放的数据一般是用来作为偏移地址
使用的,因为偏移地址当然是在基址地址上的偏移了。偏移地址是在段寄存器中存储的,关于段寄存器的介绍,我们后面再说。
CX 寄存器
CX 是数据寄存器,能够暂存一般性数据。同样为了适应以前的 8 位 CPU ,而可以将 CX 当做两个独立的 8 位寄存器使用,即有 CH 和 CL。除此之外,CX 也是有其专门的用途的,CX 中的 C 被翻译为 Counting 也就是计数器的功能。当在汇编指令中使用循环 LOOP 指令时,可以通过 CX 来指定需要循环的次数,每次执行循环 LOOP 时候,CPU 会做两件事
- 计数器自动减 1
- 判断 CX 中的值,如果 CX 中的值为 0 则会跳出循环,而继续执行循环下面的指令,当然如果 CX 中的值不为 0 ,则会继续执行循环中所指定的指令 。
DX 寄存器
除用作通用寄存器外,在I/O指令中可用作端口地址寄存器,乘除指令中用作辅助累加器,支持 MUL 和 DIV 指令。同时也支持数值溢出等。
段寄存器
CPU 包含四个段寄存器,用作程序指令,数据或栈的基础位置,它们分别是代码段寄存器CS、数据段寄存器DS、堆栈段寄存器SS、附加段寄存器ES、由它们给出相应逻辑段的首地址,称为“段基址”。
- CS(Code Segment) :代码寄存器,程序代码的基础位置
- DS(Data Segment):数据寄存器,变量的基本位置
- SS(Stack Segment):栈寄存器,栈的基础位置
- ES(Extra Segment):其他寄存器,内存中变量的其他基本位置。
指针和变址寄存器
这组寄存器存放的内容是某一段内地址偏移量,用来形成操作数地址,主要在堆栈操作和变址运算中使用:
- BP(Base Pointer):基础指针,它是栈寄存器上的偏移量,用来定位栈上变量
- SP(Stack Pointer): 栈指针,它是栈寄存器上的偏移量,用来定位栈顶
- SI(Source Index): 变址寄存器,用来拷贝源字符串
- DI(Destination Index): 目标变址寄存器,用来复制到目标字符串
状态和控制寄存器
IP(Instruction Pointer):指令指针寄存器,它是从 Code Segment 代码寄存器处的偏移来存储执行的下一条指令
FR : FR 寄存器用于存储当前进程的状态,这些状态有
位置 (Direction):用于数据块的传输方向,是向上传输还是向下传输
中断标志位 (Interrupt) :1 - 允许;0 - 禁止
陷入位 (Trap) :确定每条指令执行完成后,CPU 是否应该停止。1 - 开启,0 - 关闭
进位 (Carry) : 设置最后一个无符号算术运算是否带有进位
溢出 (Overflow) : 设置最后一个有符号运算是否溢出
符号 (Sign) : 如果最后一次算术运算为负,则设置 1 =负,0 =正
零位 (Zero) : 如果最后一次算术运算结果为零,1 = 零
辅助进位 (Aux Carry) :用于第三位到第四位的进位
奇偶校验 (Parity) : 用于奇偶校验
重点提及下CS和IP,CS(Code Segment)是代码段寄存器,一般也被称为段基址,可以认为是程序访问的入口,CPU 需要从 CS 中找到从哪个位置开始取指执行,但是我们还不知道要取哪一段,这时候 IP 的作用就体现出来了,IP(Instruction Pointer)就是指令指针寄存器,也叫做偏移地址,它会告诉我们从段基址开始,取哪一段的地址,可以使用段基址:偏移地址来确定内存中的指定地址,它们指出了 CPU 当前需要读取指令的地址。
CPU寻址
16位的CPU是什么?
- CPU 内部的运算器一次最多能处理 16 位的数,
- 寄存器的最大宽度为 16 位,通用寄存器能处理的二进制数的最大位数
- 寄存器和运算器之间的通路为 16 位,寄存器和运算器之间的总线,一次能传输 16 位的数据
CPU 相关组件提供两个地址:段地址和偏移地址,这两个地址都是 16 位的,他们经由地址加法器
变为 20 位的物理地址,这个地址即是输入输出控制电路传递给内存的物理地址,由此完成物理地址的转换。
地址加法器采用 「物理地址 = 段地址 * 16 + 偏移地址」 的方法用段地址和偏移地址合成物理地址。
这篇关于应知应会的硬核知识--寄存器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!