Z80中A寄存器异或如何清除F寄存器的进位位?

How does XORing the A register clear the carry bit on the F register in the Z80?

我正在阅读一本关于 Zilog Z80 处理器的书,其中每当作者出于可能的原因想要清除进位位时,他都会执行以下任一操作:

XOR A
AND A
OR  A

这对 F 寄存器中的 C 位有何影响?换句话说,对某个寄存器(A)执行操作如何影响另一个寄存器(F)?

应用于 A 寄存器本身的那 3 个逻辑运算不会修改 A(除了将其清零的 XOR)。

但是,作为副作用,所有这些指令都保证清除进位位,如 Z80 参考手册中所述。

这个副作用就是这里想要的效果。 OR A不会做任何清除C的事情,并且还会影响其他标志(取决于A的初始值是否为零,寄存器Z也是set/cleared)

来自OR instruction description

Effects: C and N flags cleared, P/V detects parity, ...

加法或减法overflows/underflows(ADD、SUB、ADC、SBC)时设置进位位。例如,您可以通过执行零 + 零的加法来清除 C 标志,但这需要比 OR AAND AXOR A 更多的指令,从而使后者更有效。

其他一些 8 位处理器,如 6502,有特定的 CLC/SEC 指令来清除进位,不需要这种副作用来做到这一点。

addsubtract 指令(或类似的 incdec 将属于同一类别)将借用或结转到下一个更高位 "above" 寄存器。

影响标志的基于 ALU 的命令(即除 LD x、y 和分支指令之外的大多数命令)根据此 "borrow" 行为设置或清除 C 位。纯逻辑(AND、OR、XOR)指令没有借位或进位行为,因为它们只影响寄存器中的 8 位,从而清除进位标志。

编辑:如果你想知道 "how that is done" - 因为 CPU 是这样构建的,内部 "wiring" 强制 C 位成为逻辑 over/underflow 运算后的 ALU。这不是您似乎理解的 "side effect",而是一个非常重要的,因为标志是在 Z80 程序集中基于逻辑决策(即 "IF" 子句)的唯一方法。

大多数处理器都是使用我们所说的微代码创建的。一条微码指令做一件非常小的事情。

所以我们可以证明 OR A 指令做了这样的事情:

OR A     tmp ← A              modify register "tmp"
         tmp ← tmp | A        apply OR and save result in "tmp"
         A ← tmp              copy "tmp" back to A
         F[C] ← 0             clear C flag
         F[Z] ← A == 0        set Z to 1 if A == 0, zero otherwise
         F[N] ← A[7]          set N to sign bit of A

请注意,由于这对 A 没有影响,他们可以重命名指令 CLC(清除进位)。

正如其他人所说,清除 C 标志是 z80 设计人员决定的选择。大多数处理器不会影响逻辑操作的 C 标志(AND、OR、XOR、NAND...)

我想我理解你的担忧。标志寄存器获取操作的结果,因此 AND、OR、XOR 都会影响零标志、符号标志和奇偶校验标志。这些都是结果的直接属性。但是操作不是算术运算,所以进位不是自然的 属性.

我想答案就在ALU本身。作为程序员,我们将 ALU 视为一个多功能盒。你给它一个值和一个操作,它在累加器设置标志上执行该操作作为副产品。在内部,我们怀疑它的每个操作都有一个单独的电路:加、减、与、或、异或。

实际上它更像是一个多用途函数,可以修改每一位来执行所需的操作。在高层次上,我们可以看到加法与进位加法的对比。在内部,这些指令的唯一区别是在执行加法时是否使用进位标志。类似地,减法只是将数字的二进制补码相加。所以减法只是操作数的一些前端变化,并使用相同的加法电路。

现在考虑我们如何对单个位进行加法。忽略进位,注意 0+0 = 0、0+1 = 1+0 = 1 和 1+1 = 0。那么进位呢?进位(0+0) = 进位(0+1) = 进位(1+0) = 0 和进位(1+1) = 1.

认识那些功能?两位的进位是它们的与。两位相加的结果是它们的异或。如果你进一步扩展这个想法,你会看到一个简单的电路如何将两个位与一个进位输入相加,并产生结果位和一个进位输出。将其中的 8 个链接在一起,您就是在添加数字。

如果您正在设计处理器,您可能还会注意到您几乎可以免费获得 XOR。 XOR 只是将两个数字加在一起,但阻止进位从一位到位。类似的快捷方式可以提取您通常从进位计算中获得的 AND 值,我敢肯定还有其他一些技巧可以在其中找到 OR 。细节在这里变得非常重要,因为 Z-80 的设计者没有使用 AND 和 XOR 门,而是使用原始晶体管逻辑,它可以从电路中产生更灵活的东西。

无论如何,现在有一个选择。我们的 XOR 将每个位之间的进位归零。第8位呢?好吧,我们也应该将其归零。否则,进位位将是符号位的 AND,这似乎会使汇编程序员感到困惑和烦恼,而且没有多大用处。但是,如果我们像对其他所有进位一样将进位归零,那么我们就会得到一个漂亮的对称电路,并且结果清晰明确。而且,我怀疑,将值归零比忽略它更容易。

因此,让零进位通过可以为我们节省几个晶体管。这种副作用在像 "OR A,A" 或 "AND A,A" 这样的操作中派上用场,否则它们不会做很多事情。现在,Z-80 继承了 8080 的这种行为,所以它实际上是 8080 设计师的选择,而不是 Z-80。你可以看到他们在指令集中考虑了这一点,因为他们只给了我们两个直接影响进位的操作:SCF - 将进位标志设置为 1 和 CCF - 补充进位标志。他们明确避免给我们 "clear carry flag" 因为 "OR A,A" 已经免费提供了。因此整个业务节省了整个指令。而且,我们只能假设,他们认为将逻辑运算中的进位标志归零对编程来说并不是很大的障碍。在大多数情况下,您要么进行逻辑计算,要么进行算术计算,因此逻辑运算切换进位并不是什么大问题。显然其他 CPU 设计师不同意,但这是一个公平的选择。

底线:清除进位是电路的自然结果,8080 设计人员认为这是一个有用的副作用,因此选择保留它而不是添加电路来抑制它。

具体细节见Z-80 ALU operates internally and the 8085 ALU internals.