EAX x86 寄存器的含义和历史

1,973 阅读7分钟
原文链接:keleshev.com/eax-x86-reg…

x86教程通常不会花太多时间从历史的角度告诉它的设计思路以及命名规则。在学习x86架构的汇编语言时,我们经常遇到的是:

给你EAX,它是一个寄存器,随便用吧。

那么,E-A-X这三个字母究竟是什么意思呢?

答案恐怕没这么简单!让我们回到1972年...

8008

在1972年,在经历一系列事件之后,Intel发布了世界第一款8位微处理器:8008。

之前,Intel是存储器芯片的主要卖家。8008的产生是源于Computer Terminal Corporation (CTC) 委托Intel制造一款处理器,用于其新款Datapoint 2200可编程终端。但是8008的制造延期了,且没能满足CTC的需求。所以Intel往8008里加入了一些通用指令后,卖给了其它客户。

  

                                          Datapoint 2200

8008有7个8位寄存器。

A 代表累加器(accumulator),它作为一个隐含的操作数(operand),返回经算数运算(arithmetic)和逻辑运算(logical)后的值。

你可能会想,我的妈,7个寄存器,这个数字也太奇(ji)怪了。

确实很奇怪。将这些寄存器其中的3位作为指令位,能够得到8种组合(译者按:2的三次方)。最后还有一个“伪(pseudo)”寄存器叫做M(译者按:和前7个寄存器加起来共8个寄存器),它代表内存(memory)。

M 表示了内存地址,由寄存器HL 组成。H表示内存的高位字节部分,L表示内存的地位字节部分。这是8008中唯一读取内存的方式。

总之,A代表累加器。HL结合起来表示内存地址。B, C, D, E则是通用寄存器,用以数据交换。

8086

在1979年,Intel已经完全是一个处理器生产商了,与此同时它的旗舰处理器iAPX 432又延期了。为了填补空缺,Intel推出了16位的8086处理器,它是8080的衍生品,而8080又基于8008。

为了扩大客户基础,8086向后兼容了8008,用一个简单的程序将8008汇编转译成8086。为了使之工作无误,8086指令集架构必须够好地映射到8008,所以就必须继承8008的大多数设计决策。

8086有8个16位的寄存器,8个8位的寄存器,它们有重叠的部分如下图所示:

8086指令内有一个flag位,标注了寄存器的3位指令位是指向8位寄存器还是16位寄存器。

通过上图你可以看到,前4个16位寄存器的数据可以被8个8位寄存器读到。

AX是一个16位的累加器。与此同时,AHAX可以代表其自身,也可以分别代表AX的高位字节和低位字节。

AX中的X是一个占位符,代表H或者L

这里的“x”和x86代表8086,80186, 80286等等是一个意思。

因为8008只有7个8位寄存器,所以可以非常好的映射到8086的8个寄存器上,还多出一个。

自8086以后,M伪寄存器就不再需要了,因为8086有多种内存寻址模式。

通过下图你可以清晰看出8008寄存器与8086寄存器之间的映射关系:

此时,尽管大部分算数和逻辑操作都能在任意寄存器上进行,但这些寄存器已不再是真正意义上通用的了。

BX是基址寄存器,CX计算寄存器,DX数据寄存器,AX仍然是累加器。

新增的SP代表栈指针,BP代表基址指针,SI代表源索引,DI代表目标索引。不过这里我们不做深入研究。

8086还引入了段寄存器(segment registers)。分段架构自成体系,因为它的产生是为了向后兼容8080。

x86

1985年Intel推出了80386,这是x86产品线上的第一款32位处理器。而最早一批这款处理器在其中一个32位操作中存在在缺陷,Intel将其打上16-BIT S/W ONLY(仅能运行16位程序)的标签,依旧卖了出去。

80386增加了许多新特效,但依然向后兼容8086。

其主要寄存器扩展为了32位,并新增一个前缀E

EAX代表扩展AXAX表示EAX的低位部分,AHAL仍然表示AX的两个字节。

这就是EAX名称的来历。不过还没完。

x86-64

在2003年,AMD引领了处理器的潮流并推出了第一款x86架构的64位处理器。

根据传统,它向下兼容了8086。

8个主要的寄存器扩展为了64位。

这些扩展了的寄存器用R代替了E作前缀。所以我们看到累加器现在变成了RAX

为什么用R?

嗯,AMD想统一寄存器的命名(streamline the register handling)。他们引入了8个新的寄存器命名从R8R15。与此同时,他们还讨论要不要将已有的8个寄存器命名成R0R7。但是他们注意到很多指令助记符里包含了一些代表寄存器的字母比如AB。所以他们保留了原始命名,只将E替换成了R。这至少也与R8R15保持了一些一致性。

所以,RAX中的R代表了寄存器(register),并且与新增寄存器R8-R15保持了命名上的一致性。


新寄存器依然有它的小(narrow)版本(译者按:也就是R15D,R15W,R15B。D代表Double,W代表Word,B代表Byte。)。拿R15做例子,如下图所示:

终于,朋友们,这就是x86寄存器简史。从8008的8位的A,到8086的16位的AX,到80386的32位的EAX,再到64位的RAX


(译者按:最后一段Correction部分不想译了,是8086架构师Steve Morse的对原作者的回信。Steve Morse谈及了命名历史,并表示40多年过去了,当年的很多细节也记不大清了。时间最无情。)

Correction

An earlier version of this blog post stated that the X in AX stood for eXtended.

Some of you pointed out that this was not quite right and that the X stood, in a way, for “pair.” I must admit that, unlike for the rest of the article, I couldn’t find a reference that authoritatively described the meaning of X. So, I decided to reach out to Dr. Stephen Morse, the architect of 8086.

With his permission, I include the response:

Vladimir,

Your question is certainly pushing my memory about decisions that were made over 40 years ago. So the following is the best of my recollection and not necessarily 100% accurate.

Prior to the 8086 the registers were single letters, e.g., A, B, C, D. Each was an 8-bit register. The 8086 had 16-bit registers that could be referenced either 8-bits at a time or all 16-bits at once. For example, we could reference the 8 high-order bits of the A register, the 8 low-order bits of the A register, or the entire 16 bits of the A register. The nomenclature of the first two were chosen to be AL and AH, where the L/H designated the low-order or the high order half. Now we needed a term to designate the full 16 bits. So the letter X was selected. The X was simply an arbitrary letter that combined both L and H – sort of like the use of X in algebra to designate the unknown. There really wasn’t that much thought given as to what X stood for (if anything) – it was just a letter that was needed to identify the General Registers (AX, BX, CX, DX), as opposed to the Pointer and Index Registers (SP, BP, SI, DI), and the Segment Registers (CS, DS, ES, SS).

– Steve Morse