为什么32位寄存器分为4个部分?

时间:2011-10-23 19:42:46

标签: cpu-registers

我正在学习寄存器。看起来32位寄存器被分割,因此可以作为8位寄存器进行访问。这看起来非常低效。如果不这样做,性能会得到改善。那他们为什么这么做呢?

此外,这样设计它们需要额外的费用。为什么不通过不这样做使CPU更便宜?

4 个答案:

答案 0 :(得分:2)

因为如果你只处理8位值,那么发出所有位掩码将这些32/64位寄存器限制为你正在处理的8位是没有效率的。

所以,x86寄存器有

AH/AL = high/low 8bits of a 16bit register
AX = whole 16bit register
EAX = whole 32bit register

就指令大小而言,它的效率要高得多

mov ah, 0xXX   (2 bytes)

而不是强迫

mov ax, 0x00XX  (3 bytes)
mov eax, 0x000000XX  (7 bytes)

至于“设计cpu使其更便宜” - 这是为了向后兼容。所有现代x86处理器实际上都是内部的RISC设计,主要有一大块硅片用于接收x86指令并将它们转换为CPU自己的内部微操作(基本上是RISC指令集)。

答案 1 :(得分:2)

英特尔8080是第一款“主流”微处理器,有7个主要的8位寄存器(A,B,C,D,E,H和L)。因为存储器地址是16位,所以需要使用非常量存储器操作数的指令将使用一对寄存器(最常见的是H和L,但有时是B和C,或D和E)来形成地址。由于上述对中的寄存器通常一起用于表示16位值,因此有一些指令可以在寄存器对上作为16位量进行操作。将BC添加到HL的指令将通过将C添加到L,然后通过将B添加到H(如果需要加上进位)来执行添加。我不熟悉4004或8008(8080的两个前辈),知道他们中的任何一个是否在其架构中做了类似的事情。

当英特尔生产8088时,它们包括一个完整的16位算术单元,但他们希望为8080编写的代码可以轻松转换为新的架构。在8080上,许多代码已经写入8位部分的“手动”形式地址,因为这样做通常比使用16位指令进行数学运算要快得多。例如,如果需要访问某个指定的256个条目表并且索引存储在A中,则可以执行类似的操作(Zilog符号显示,但8080具有相同的指令):

ld   hl,(baseOfTable) ; 16-bit address
ld   c,a
ld   b,#0
add  hl,bc
ld   a,(hl)

但如果可以确定表是在256字节边界上对齐的,那么可以大大简化代码:

ld   l,a
ld   a,(tableBaseMSB) ; Just load the MSB--assume the LSB is zero
ld   h,a
ld   a,(hl)

使用8088指令集,对于“从头开始”分别访问寄存器的上部和下部的代码来说,通常不会有用,但是为8080编写的代码使用了这些技术。 ,并且英特尔希望让人们能够轻松地转换这些代码以便在8088上使用。在这方面允许从8位片段构建寄存器是有帮助的。

顺便提一下,英特尔的架构还有另一个优点:因为它包含四个仅16位寄存器和四个寄存器,可用作一个16位或两个8位部分,这使得代码可以保持寄存器中有12个值,如果它们中的8个是255或更少,或者如果其中6个是256或更少,则为11个值等。当使用具有更多寄存器的架构时,在这里寻找额外的寄存器并不是那么重要,但是在8088上它通常非常有帮助。

答案 2 :(得分:1)

当用作32位寄存器时,寻址部分寄存器的能力对其性能没有影响。在这种情况下,不使用此功能。

CPU,无论其原始位大小,都需要非常频繁地操作8位值。例如,文本字符串经常被操作为连续的8位值。国际字符集通常被操作为一组连续的16位值。因此能够在8位和16位值上快速运行是非常重要的。

如果你问x86 CPU的实际问题,那就太晚了。最初的PC CPU甚至没有32位寄存器,并且一直保持兼容性。

答案 3 :(得分:1)

向后兼容性。处理器制造商不想破坏与旧软件的兼容性。这是x86_64处理器仍然支持16位软件(虚拟模式)的主要原因。如果仔细观察,您会发现x86架构中的大多数功能都受到兼容性问题的影响。我不讨厌。