%AX =(%AH +%AL)

那么为什么%EAX =(%SOME_REGISTER +%AX)对于某些寄存器%SOME_REGISTER

有帮助吗?

解决方案

只是为了澄清一下。在1970年代早期的微处理器时代,CPU只有少量的寄存器和非常有限的指令集。通常,算术单元只能在单个CPU寄存器上操作,通常称为“累加器”。 8位8080& 8上的累加器Z80处理器被称为“A”。还有6个其他通用8位寄存器:B,C,D,E,H&这六个寄存器可以配对形成3个16位寄存器:BC,DE& HL。在内部,累加器与Flags寄存器组合在一起形成AF 16位寄存器。

当英特尔开发出16位8086系列时,他们希望能够移植8080代码,因此它们保持相同的基本寄存器结构:

8080/Z80  8086
A         AX
BC        BX
DE        CX
HL        DX
IX        SI    
IY        DI

由于需要移植8位代码,因此需要能够参考AX,BX,CX和CD的各个8位部分。 DX。这些被称为AL,AH为低和低。 BL / BH,CL / CH&的高字节AX等等DL / DH。 IX& Z80上的IY仅用作16位指针寄存器,因此无需访问SI和EX的两半。 DI。

当80386在20世纪80年代中期发布时,他们创造了“扩展”。所有寄存器的版本。因此,AX成为EAX,BX成为EBX等。不需要访问这些新扩展寄存器的前16位,因此它们没有创建EAXH伪寄存器。

AMD在生产第一批64位处理器时应用了相同的技巧。 AX寄存器的64位版本称为RAX。所以,现在你有了这样的东西:

|63..32|31..16|15-8|7-0|
               |AH.|AL.|
               |AX.....|
       |EAX............|
|RAX...................|

其他提示

这里发布了很多答案,但没有一个真正回答给定的问题:为什么没有一个寄存器直接编码高16位的EAX或高32位的RAX?答案归结为x86指令编码本身的局限性。

16位历史课

当英特尔设计8086时,他们对许多指令使用了可变长度编码方案。这意味着某些非常常见的指令,如 POP AX ,可以表示为单个字节(58),而罕见(但仍然可能有用)指令,如 MOV CX,[BX * 4 + BP + 1023] 仍然可以表示,即使它需要几个字节来存储它们(在本例中,8B 8C FF 03)。

这似乎是一个合理的解决方案,但是当他们设计它时,他们填写了大部分可用空间。因此,例如,八个单独的寄存器(AX,CX,DX,BX,SP,BP,SI,DI)有八个 POP 指令,它们填写了操作码58到5F,并且操作码60完全是另一回事( PUSHA ),操作码57( PUSH DI )也是如此。在那之后或之前没有任何余地。甚至推送和弹出段寄存器—这在概念上几乎与推送和弹出通用寄存器相同[—必须在不同的位置进行编码(低于06 / 0E / 16 / 1E),因为其余的推/弹指令旁边没有空间。

同样地,“mod r / m”用于复杂指令的字节,如 MOV CX,[BX * 4 + BP + 1023] 只有三位用于编码寄存器,这意味着它总共只能代表8个寄存器。如果你只有8个寄存器,这很好,但如果你想拥有更多的寄存器,那就是一个真正的问题。

(这里有x86架构中所有这些字节分配的优秀地图: http://i.imgur.com/xfeWv .png 。注意主映射中没有剩余空间,一些指令重叠字节,甚至由于MMX和SSE指令,现在使用了多少辅助“0F”映射。)

走向32位和64位

因此,为了甚至允许CPU设计从16位扩展到32位,它们已经存在设计问题,并且他们用前缀字节解决了这个问题:通过添加特殊的“66”来解决这个问题。在所有标准16位指令前面的字节,CPU知道你想要相同的指令但是32位版本(EAX)而不是16位版本(AX)。设计的其余部分保持不变:整体CPU架构中仍然只有8个通用寄存器。

必须采取类似的措施将架构扩展到64位(RAX和朋友);在那里,通过添加另一组前缀代码( REX ,40-4F)来解决该问题,该前缀代码意味着“64位”。 (并有效地将另外两位添加到“mod r / m”字段),并且还丢弃了没有人使用的奇怪的旧指令,并将其字节代码重新用于更新的东西。

8位寄存器旁边

要问的一个更大的问题是,如果在8个寄存器的设计中只有真正的空间,那么像AH和AL这样的东西是如何起作用的。答案的第一部分是没有“ PUSH AL ”这样的东西。 —有些指令根本无法对字节大小的寄存器进行操作!唯一可能是一些特殊的奇怪(如 AAD XLAT )和特殊版本的“mod r / m”指令:通过在“mod r / m”中翻转非常特定的位。字节,那些“扩展指令”可以翻转进行操作

在旧的8位日里,有一个A寄存器。

在16位时间内,有16位AX寄存器,当你还想使用8位值的时候,它被分成两个8位部分AH和AL。

在32位时间内,引入了32位EAX寄存器,但是AX,AH和AL寄存器都被保留了。设计人员认为没有必要引入一个新的16位寄存器来寻址EAX的16到31位。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top