本章开始构建一个八位CPU,它是Intel 8080微处理器的功能子集。
从算术逻辑单元(ALU)开始。在下面的电路中,ALU分为两部分:第一部分是处理加法和减法的算术单元,第二部分处理按位逻辑运算。
此电路实现加法和减法。顶部的两个"旋转控件"允许您选择两个要相加的十六进制数字。点击每个数字右侧的箭头可递增或递减1。左侧的箭头将数字递增或递减16(十六进制10)。
左上角的两个按钮允许您选择四个功能之一:Add、Add with Carry、Subtract和Subtract with Borrow。
底部的十六进制Result显示结果。进位由左侧的CY In按钮和右侧的CY Out指示灯处理。
这与书中显示的电路略有不同,因为CY In和CY Out的值在减法时会被反转。(第322页表格右下角的条目应为CY)
8位CPU必须能够加减16位、24位、32位等数字。因此,它必须能够保存8位加法或减法的进位,并在下一次运算中使用。
对于Add功能,左侧的CY In按钮无效。Result是两个数字和的低字节,范围从00h到FFh。如果和超过255,CY Out位将设为1。
对于Add with Carry,CY In按钮通过将加法器的CI输入设为1,使两个数字的和加1。
当相加两个多字节数字时,对最低有效字节对使用Add。对于后续的字节对,使用Add with Carry并将CY In设为前一对字节相加得到的CY Out值。
您可以尝试相加一些16位数字的示例。以下是一些可用的示例数字:
十进制 | 十六进制 |
---|---|
10,000 | 2710h |
15,000 | 3A98h |
20,000 | 4E20h |
25,000 | 61A8h |
30,000 | 7530h |
40,000 | 9C40h |
例如,相加2710h和7530h。分两步进行:首先Add10h和30h,结果是40h且CY Out设为0。然后Add with Carry高字节27h和75h,CY In设为0,结果是9Ch,组合结果为9C40h。
现在尝试一个有进位的例子,如相加3A98h和61A8h。首先Add低字节98h和A8h,结果是40h且CY Out设为1。然后Add with Carry高字节3Ah和61h,CY In设为1(即前一对字节相加得到的CY Out),结果是9Ch,组合结果为9C40h。
现在尝试相加7530h和9C40h。首先Add30h和40h,结果是70h且CY Out为0。然后Add with Carry75h和9Ch,CY In设为0,结果是11但CY Out值为1表示溢出。
这个溢出意味着您实际上在处理24位数字。因此,Add with Carry00h和00h,CY In设为1,结果当然是01,表示3字节组合结果为011170h或十进制的70,000。
对于Subtract功能,左侧的CY In按钮无效。通过反转B的位,将它们加到A上,再加1(通过将加法器的CI输入设为1实现)来从A中减去B的值。如果B小于或等于A,Result是差值。如果B大于A,CY Out指示灯表示需要借位。
让我们尝试一些减法,例如7530h减去4E20h。从低字节开始:将功能设为Subtract,A设为30h,B设为20h。差值是10h且CY Out设为0。然后选择Subtract with Borrow,将A和B设为高字节75h和4Eh,CY In设为0。结果是27h,组合结果为2710h。
现在尝试7530h减去3A98h。将功能设为Subtract,A设为30h,B设为98h。结果是98h且CY Out设为1。然后对高字节75h和3Ah使用Subtract with Borrow,但将CY In设为1以匹配第一对字节的CY Out值。结果是3Ah,组合结果为3A98h。
最后一个例子,尝试3A98h减去7530h。首先Subtract低字节98h和30h,结果是68h且CY Out位为0。然后Subtract with Borrow高字节3Ah和75h,CY In设为0。结果是C5h,组合结果为C568h,但CY Out值为1表示溢出。
下一步可以像处理加法溢出那样,将计算扩展到24位。再次选择Subtract with Borrow,但将A和B都设为0,CY In设为1。现在结果是FFh且CY In仍为1。
您可以继续,但尝试使用Windows或macOS计算器的程序员模式计算3A98h减去7530h。您会得到FFFFFFFFFFFFC598h,表示等于-15,000的负数。(或者,您可以通过反转所有位并加1来计算FFFFFFFFFFFFC598h的补码。结果是3A98h,即十进制15,000。)
ALU的逻辑部分比算术部分简单得多。只需要三个执行按位AND、XOR和OR操作的盒子,以及一个选择器来选择启用哪个三态缓冲器:
与加减法单元一样,您可以为输入选择两个十六进制数字。使用左侧的按钮选择操作:
如果最左侧的按钮为0,则没有选择任何三态缓冲器,因为这是算术操作。如果按钮设为1 1 1,则是比较操作,由下一个电路处理。
算术逻辑单元结合了加减法单元和逻辑单元。书中第332页的版本有些简化,没有正确处理比较指令。处理比较指令涉及更多复杂性,如下所示:
A和B输入在顶部左右两侧设置。选择功能的按钮位于顶部中央:
左下角的Clock输入保存计算结果和三个标志的状态。右下角的Enable按钮显示结果。
前四个功能由本章前面介绍的Add/Sub模块处理。CY Out值保存在底部的Flags Latch中,然后路由回CY In输入。
逻辑功能(AND、XOR和OR)由右上方的Logic模块处理。这些功能总是清除Carry标志(即设为0),这解释了通向Flags Latch的CY输入的一些逻辑。
对于算术功能和逻辑功能AND、XOR、OR,如果结果为零,Zero标志被设置。这由电路中间的八输入NOR门处理。
复杂的是比较操作。比较操作设置Zero和Carry标志,就像发生了减法一样。如果A和B输入相等,Zero标志被设置;如果A小于B,CY标志被设置。
然而,比较操作不会在累加器中保存新值。因此,如果发生比较操作,A输入通过最左侧的三态缓冲器启用,以保存在右下角的Latch中。
对于比较操作,Add/Sub模块执行带借位的减法,因为F1和F0都为1。因此,执行比较操作时,CY In设为0。