关于Intel 8086处理器算术逻辑单元的笔记
摘要
详细的技术分析,探讨Intel 8086处理器算术逻辑单元(ALU)的控制电路,解释微码和控制信号如何协调执行28种不同操作。
<p>1978年,Intel推出了8086处理器,这是一款革命性的芯片,开创了现代x86架构。但与现代64位处理器不同,8086是16位芯片。其算术/逻辑单元(ALU)对16位值进行操作,执行算术运算(如加法和减法)以及逻辑运算(包括按位AND、OR和XOR)。8086的ALU是芯片中一个复杂的部分,总共执行28种操作。<span id="fnref:operations"><a class="ref" href="#fn:operations">1</a></span></p>
<p>在本文中,我将讨论控制ALU的电路,这些电路为特定操作生成适当的控制信号。这个过程比您想象的要复杂。首先,一条机器码指令会导致多条微码指令的执行。使用ALU是一个两步过程:一条微码指令(微指令)配置ALU进行所需操作,而第二条微指令从ALU获取结果。此外,根据微码微指令和机器码指令,控制电路向ALU发送控制信号,重新配置它以执行所需操作。因此,该电路提供了微指令和ALU之间的“粘合剂”。</p>
<p>下面的裸片照片显示了显微镜下的8086处理器。我标出了关键的功能块。从架构上看,芯片分为上方的总线接口单元(BIU)和下方的执行单元(EU)。BIU处理总线和内存活动以及指令预取,而执行单元(EU)执行指令。在右下角,微码ROM保存微指令。ALU位于左下角,位7-0在上方,位15-8在下方,夹着状态标志电路。ALU控制电路在芯片底部用红色标出,是本文的重点。</p>
<p><a href="https://static.righto.com/images/8086-alu-notes/die-labeled2.jpg"><img alt="8086的裸片,金属层已去除以显示下面的硅和多晶硅。点击此图像(或任何其他图像)查看大图。" class="hilite" height="622" src="https://static.righto.com/images/8086-alu-notes/die-labeled2-w600.jpg" title="8086的裸片。点击此图像(或任何其他图像)查看大图。" width="600" /></a><div class="cite">8086的裸片。点击此图像(或任何其他图像)查看大图。</div></p>
<h2>微码</h2>
<p>8086处理器用微码实现大多数机器指令,每个机器指令步骤对应一条微指令。(我在此处详细讨论了8086的微码<a href="https://www.righto.com/2022/11/how-8086-processors-microcode-engine.html">链接</a>)。8086使用了一种有趣的微码架构:每条微指令执行两个不相关的操作。第一个操作在源和目标之间移动数据。第二个操作可以是跳转或子程序调用、内存读/写或ALU操作。ALU操作有一个五位字段来指定特定操作,以及一个两位字段来指定哪个临时寄存器提供输入。如下文所示,这两个字段在ALU电路中起重要作用。</p>
<p>在许多情况下,8086的微指令并不指定ALU操作,而是将细节从机器指令操作码中替换出来。例如,ADD、SUB、ADC、SBB、AND、OR、XOR和CMP机器指令共享相同的微码,而硬件从指令操作码中选择ALU操作。同样,递增和递减指令使用相同的微码,十进制调整指令DAA和DAS也是如此,ASCII调整指令AAA和AAS也是如此。在微指令内部,所有这些操作都使用一个称为XI(出于某种原因)的“伪”ALU操作来执行。如果微码指定了XI ALU操作,硬件会将其替换为指令中指定的ALU操作。微码的另一个重要特点是,您需要执行一条ALU微指令来配置ALU的操作,但结果要到后面的微指令才可用,该微指令将结果移动到目标。这导致硬件必须记住ALU操作。</p>
<p>为了具体说明,这里展示了实现典型算术指令(如<code>ADD AL, BL</code>或<code>XOR [BX+DI], CX</code>)的微码。该微码由三条微指令组成。每条微指令的左侧部分指定数据移动,首先将两个参数移动到ALU临时寄存器,然后存储ALU结果(称为Σ)。每条微指令的右侧部分执行第二个任务。首先,ALU被配置为使用临时寄存器A执行<code>XI</code>操作。回想一下,<code>XI</code>表示ALU操作从机器指令中填充;这就是相同微码处理八种不同类型机器指令的方式。在第二条微指令中,除非需要内存写回(<code>WB</code>),否则开始下一条机器指令。最后一条微指令是<code>RNI</code>(运行下一条指令)以开始一条新的机器指令。它还指示处理器状态标志(<code>F</code>)应该更新,以指示ALU结果是否为零、正数、溢出等。<span id="fnref:addressing"><a class="ref" href="#fn:addressing">2</a></span></p>
<style>
pre.microcode {font-family: courier, fixed; padding: 10px; background-color: #f5f5f5; display:inline-block;border:none;}
pre.microcode span {color: green; font-style:italic; font-family: sans-serif; font-size: 90%;}
</style>
<pre class="microcode">
M → tmpa XI tmpa <span>加载第一个参数,配置ALU。</span>
R → tmpb WB,NXT <span>加载第二个参数,如果没有内存写回则开始下一条指令</span>
Σ → M RNI F <span>存储ALU结果,运行下一条指令,更新状态标志</span>
</pre>
<h2>ALU电路</h2>
<p>ALU是处理器的核心,执行算术和逻辑运算。1970年代的微处理器通常支持加法和减法;逻辑AND、OR和XOR;以及各种移位操作。(虽然8086具有乘法和除法指令,但这些是通过微码实现的,而不是在ALU中。)由于ALU既大又对性能至关重要,芯片架构师试图优化其设计。因此,不同微处理器有着截然不同的ALU设计。例如,6502微处理器有独立的电路分别用于加法和每种逻辑操作;一个多路选择器选择适当的输出。相比之下,Intel 8085使用一组优化的门电路,根据控制信号执行所需操作(<a href="https://www.righto.com/2013/01/inside-alu-of-8085-microprocessor.html">详情</a>),而Z80的4位ALU使用另一组不同的门电路(<a href="https://www.righto.com/2013/09/the-z-80-has-4-bit-alu-heres-how-it.html">详情</a>)。</p>
<p>8086采用了一种不同的方法,使用两个查找表(以及其他门)为ALU中的每个位生成进位和输出信号。通过适当设置查找表,ALU可以配置为执行所需操作。(这类似于FPGA通过查找表实现任意函数的方式。)下面的原理图显示了ALU一位的电路。我不会详细解释这个电路,因为我在<a href="https://www.righto.com/2020/08/reverse-engineering-8086s.html">之前的一篇文章</a>中已经解释过了。<span id="fnref:shift-right"><a class="ref" href="#fn:shift-right">3</a></span>这个电路的相关部分是左侧的六个控制信号。两个多路选择器(梯形符号)通过使用t</p>
查看缓存全文
缓存时间: 2026/05/16 03:32
# Intel 8086 处理器算术逻辑单元笔记
来源:http://www.righto.com/2026/01/notes-on-intel-8086-processors.html
1978年,Intel 推出了 8086 处理器,这款革命性芯片奠定了现代 x86 架构的基础。然而,与现代 64 位处理器不同,8086 是一款 16 位芯片。其算术逻辑单元(ALU)操作 16 位数值,执行加法、减法等算术运算,以及按位与、或、异或等逻辑运算。8086 的 ALU 是芯片中一个复杂的部分,总共执行 28 种操作。1 (http://www.righto.com/2026/01/notes-on-intel-8086-processors.html#fn:operations)
在这篇文章中,我将讨论控制 ALU 的电路,该电路为特定操作生成适当的控制信号。这个过程比你想象的要复杂。首先,一条机器码指令会导致执行多条微码指令。使用 ALU 是一个两步过程:一条微码指令(微指令)将 ALU 配置为所需操作,而第二条微指令则从 ALU 获取结果。此外,基于微码微指令和机器码指令,控制电路向 ALU 发送控制信号,将其重新配置为所需操作。因此,该电路提供了微指令与 ALU 之间的“粘合剂”。
下面的芯片显微照片显示了显微镜下的 8086 处理器。我标注了关键功能块。从架构上看,芯片分为顶部的总线接口单元(BIU)和下方的执行单元(EU)。BIU 处理总线和存储器活动以及指令预取,而执行单元(EU)执行指令。在右下角,微码 ROM 保存着微指令。ALU 位于左下角,位 7-0 在上方,位 15-8 在下方,夹着状态标志电路。ALU 控制电路以红色突出显示在芯片底部,是本文的重点。
8086 芯片的显微照片,去除了金属层以显示下面的硅和多晶硅。点击此图片(或任何其他图片)可查看大图。(https://static.righto.com/images/8086-alu-notes/die-labeled2.jpg)
8086 芯片的显微照片。点击此图片(或任何其他图片)可查看大图。
## 微码
8086 处理器通过微码实现大多数机器指令,机器指令的每一步都对应一条微指令。(我在此处详细讨论了 8086 的微码 (https://www.righto.com/2022/11/how-8086-processors-microcode-engine.html)。)8086 使用了一种有趣的微码架构:每条微指令执行两个不相关的操作。第一个操作在源和目的地之间移动数据。第二个操作可以是跳转或子程序调用,也可以是内存读/写或 ALU 操作。ALU 操作有一个五位字段来指定特定操作,以及一个两位字段来指定哪个临时寄存器提供输入。如下所述,这两个字段在 ALU 电路中起着重要作用。
在许多情况下,8086 的微指令并不指定 ALU 操作,而是将细节留给机器指令操作码来替代。例如,ADD、SUB、ADC、SBB、AND、OR、XOR 和 CMP 机器指令共享相同的微码,而硬件从指令操作码中选择 ALU 操作。同样,递增和递减指令使用相同的微码,十进制调整指令 DAA 和 DAS 也是如此,ASCII 调整指令 AAA 和 AAS 也是如此。在微指令内部,所有这些操作都通过一个称为 XI 的“伪”ALU 操作来执行。如果微码指定了 XI ALU 操作,硬件会将其替换为指令中指定的 ALU 操作。微码的另一个重要特性是,你需要执行一条 ALU 微指令来配置 ALU 的操作,但结果直到后面的微指令才可用,该微指令将结果移动到目的地。这导致硬件必须记住 ALU 操作。
为了具体说明,以下是实现典型算术指令(如 `ADD AL, BL` 或 `XOR [BX+DI], CX`)的微码。该微码由三条微指令组成。每条微指令的左半部分指定数据移动,首先将两个参数移动到 ALU 临时寄存器,然后存储 ALU 结果(称为 Σ)。每条微指令的右半部分执行第二个任务。首先,ALU 被配置为使用临时寄存器 A 执行 `XI` 操作。回想一下,`XI` 表示 ALU 操作由机器指令填充;这就是同一条微码如何处理八种不同机器指令类型的原因。在第二条微指令中,除非需要内存写回(`WB`),否则启动下一条机器指令。最后一条微指令是 `RNI`(运行下一条指令),用于启动一条新的机器指令。它还指示更新处理器状态标志(`F`),以指示 ALU 结果是否为零、正数、溢出等。2 (http://www.righto.com/2026/01/notes-on-intel-8086-processors.html#fn:addressing)
```
M → tmpa XI tmpa 加载第一个参数,配置 ALU。
R → tmpb WB,NXT 加载第二个参数,如果不需要内存写回,则启动下一条指令。
Σ → M RNI F 存储 ALU 结果,运行下一条指令,更新状态标志。
```
## ALU 电路
ALU 是处理器的核心,执行算术和逻辑运算。1970 年代的微处理器通常支持加法、减法、逻辑与、或、异或以及各种移位操作。(尽管 8086 有乘法和除法指令,但这些是通过微码实现的,而不是在 ALU 中。)由于 ALU 既庞大又对性能至关重要,芯片架构师会尝试优化其设计。因此,不同的微处理器有着截然不同的 ALU 设计。例如,6502 微处理器为加法和每种逻辑操作分别设有独立电路,并通过多路复用器选择相应输出。而 Intel 8085 则使用一簇优化过的门电路,根据控制信号执行所需操作(详情 (https://www.righto.com/2013/01/inside-alu-of-8085-microprocessor.html))。Z80 的 4 位 ALU 则采用了另一簇不同的门电路(详情 (https://www.righto.com/2013/09/the-z-80-has-4-bit-alu-heres-how-it.html))。
8086 采用了不同的方法,使用两个查找表(以及其它门电路)来为 ALU 中的每个位生成进位和输出信号。通过适当设置查找表,ALU 可以配置为执行所需操作。(这与 FPGA 通过查找表实现任意功能的方式类似。)下面的原理图显示了 ALU 的一个位的电路。我不会详细解释这个电路,因为我在之前的一篇文章中已经解释过了 (https://www.righto.com/2020/08/reverse-engineering-8086s.html)。3 (http://www.righto.com/2026/01/notes-on-intel-8086-processors.html#fn:shift-right)该电路的相关部分是左侧的六个控制信号。两个多路复用器通过使用两个输入参数位从控制信号中选择输出来实现查找表,从而控制进位的生成和传播。因此,通过向 ALU 提供适当的控制信号,8086 可以重新配置 ALU 以执行所需操作。例如,使用一组控制信号,该电路将执行加法。其他组的控制信号将使电路执行减法或计算逻辑操作,例如 AND 或 XOR。8086 有 16 个该电路的副本,因此它可以操作 16 位数值。
实现 8086 ALU 中一个位的电路。(https://static.righto.com/images/8086-alu-notes/alu-schematic.png)
实现 8086 ALU 中一个位的电路。
8086 是一个复杂的处理器,其指令有许多特殊情况,因此控制 ALU 比上述情况更复杂。例如,比较操作与减法相同,只是比较的数值结果被丢弃,只更新状态标志。加法与带进位加法指令需要不同的进位值进入第 0 位,而减法则需要将进位标志取反,因为它被视为借位。8086 的 ALU 支持递增和递减操作,但也支持递增和递减 2,这需要将递增信号送入第 1 位而不是第 0 位。移位操作都需要特殊处理。例如,循环移位可以使用或不使用进位位,而算术右移需要复制最高位。因此,除了六个查找表控制信号外,ALU 还需要大量控制信号来针对特定指令调整其行为。在下一节中,我将解释这些控制信号是如何生成的。
## 芯片上的 ALU 控制电路
下图显示了芯片上 ALU 控制逻辑的组件。来自微指令的信息从右侧进入并存储在锁存器中。PLA(可编程逻辑阵列)对指令进行解码并生成控制信号。这些信号流向左侧,控制 ALU。
芯片上的 ALU 控制逻辑。我移除了金属层以显示下面的多晶硅和硅。微红的线条是金属的残留物。(https://static.righto.com/images/8086-alu-notes/logic-labeled.jpg)
芯片上的 ALU 控制逻辑。我移除了金属层以显示下面的多晶硅和硅。微红的线条是金属的残留物。
如前所述,如果微码指定了 `XI` 操作,则操作字段将被替换为基于机器指令操作码的值。此替换由 `XI` 多路复用器在值存储到操作锁存器之前执行。由于 8086 指令集的复杂性,`XI` 操作并不像你想象的那样直接。该多路复用器从称为“X”寄存器的特殊寄存器获取三个指令位,从指令寄存器获取另一个指令位,以及从称为组解码 ROM 的解码电路获取最后一位。4 (http://www.righto.com/2026/01/notes-on-intel-8086-processors.html#fn:xi)
回想一下,一条微指令指定 ALU 操作,而后面的微指令访问结果。因此,ALU 控制电路必须记住指定的操作,以便稍后使用。特别是,控制电路必须跟踪要执行的 ALU 操作和指定的临时寄存器。控制电路使用三个触发器来跟踪指定的临时寄存器,每个寄存器一个触发器。微指令包含一个两位字段,用于指定临时寄存器。控制电路解码该字段并激活相关的触发器。这些触发器的输出进入 ALU 并启用相关的临时寄存器。在每条机器指令开始时,5 (http://www.righto.com/2026/01/notes-on-intel-8086-processors.html#fn:sc)触发器被复位,因此默认选择临时寄存器 A。
控制电路使用五个触发器来存储来自微指令的五位操作字段。在每条机器指令开始时,触发器被复位,因此默认指定操作 0(ADD)。一个重要的结果是,加法操作有可能在没有微指令配置 ALU 的情况下执行,从而将微码缩短一条微指令,进而将指令时间缩短一个周期。
来自操作触发器的五位输出进入操作 PLA(可编程逻辑阵列)7 (http://www.righto.com/2026/01/notes-on-intel-8086-processors.html#fn:pla),它将操作解码为 27 个控制信号。6 (http://www.righto.com/2026/01/notes-on-intel-8086-processors.html#fn:control)这些信号中的许多进入 ALU,在那里它们控制 ALU 针对特殊情况的行为。大约 15 个信号进入查找表(LUT)PLA,该 PLA 为 ALU 生成六个查找表信号。在 LUT PLA 的左侧,特殊的高电流驱动电路在控制信号发送到 ALU 之前对其进行放大。关于这些驱动器的详细信息在脚注中。8 (http://www.righto.com/2026/01/notes-on-intel-8086-processors.html#fn:driver)
## 结论
每当我审视 8086 处理器的电路时,我都能看到 RISC 芯片和 CISC 芯片之间的差异。在诸如 ARM 这样的 RISC(精简指令集计算机)处理器中,指令解码和处理器电路都很直接。但在 8086 这种 CISC(复杂指令集计算机)处理器中,处处都有边界情况和复杂性。例如,一条 8086 机器指令有时在第一字节指定 ALU 操作,有时在第二字节,有时在其他地方,因此需要 X 寄存器锁存器、XI 多路复用器和组解码 ROM。8086 的 ALU 包含晦涩的操作,包括四种 BCD 调整和七种移位类型,这使得 ALU 更加复杂。当然,x86 持续的成功表明这种复杂性也有其好处。
本文深入探讨了 8086 的 ALU 的细节,但我希望你发现它很有趣。如果这对你来说过于详细,你可能更喜欢我关于 8086 ALU 的概述 (https://www.righto.com/2020/08/reverse-engineering-8086s.html)。
如需更新,请在 Bluesky (@righto.com (https://bsky.app/profile/righto.com))、Mastodon ([@[email protected]](https://oldbytes.space/@kenshirriff)) 或 RSS (http://www.righto.com/feeds/posts/default) 上关注我。
致谢:感谢 Marcin Peczarski 的讨论。我的微码分析基于 Andrew Jenner 的 8086 微码反汇编 (https://www.reenigne.org/blog/8086-microcode-disassembled/)。
## 注释与参考文献
相似文章
Intel 8087浮点芯片的指令解码
对Intel 8087浮点协处理器指令解码的详细逆向工程分析,解释主CPU与协处理器之间的交互、微码ROM的使用以及总线接口单元。
Intel 8087 浮点芯片微码中的条件
对 Intel 8087 浮点协处理器微码中使用的条件测试的详细研究,是逆向工程工作的一部分,旨在理解其算法。
386处理器寄存器的异常复杂电路
对英特尔386处理器寄存器电路的详细逆向工程分析,揭示了六种不同的定制电路和交织位存储。
Intel 386标准单元逻辑中的异常电路
探索Intel 386标准单元逻辑中的异常电路,包括大型多路复用器和非标准反相器,突出芯片的设计历史和自动布局布线技术。
Intel 8087浮点芯片的堆栈电路逆向工程
本文详细介绍了对Intel 8087浮点协处理器堆栈电路的逆向工程,解释了该芯片基于堆栈的寄存器架构和微码ROM如何实现快速浮点运算。