难道我们不能用ADD指令把8086中的两个16位数字相加吗?

Can't we use the ADD instruction to add two 16-bit numbers in 8086?

由于 8086 有一个带 16 位寄存器的 16 位 ALU,这就是我描绘的添加两个 16 位数字的方式:

MOV BX,12FFh
MOV CX,0001h
ADD BX,CX

但是我的教授说 8086 通过将 8 位数字对中的数字相加分两步而不是一步完成此操作。她说如果直接用ADD指令,lower sum产生的进位是不会结转的。她是这样解决的:

MOV BX,12FFh
MOV CX,0001h
ADD BL,CL
ADC BH,CH

她的解决方案是唯一可以接受的将两个 16 位数字相加的方法吗?

您的第一个代码块在 BX 中产生与第二个代码块相同的结果。 (在 CF 和 SF 中,我认为是 OF。不过,出于显而易见的原因,不是 ZF、PF 或 AF。)

16 位 add 不是两个单独字节加法的 SIMD 加法。如果需要,请使用 movd xmm0, ebx / movd xmm1, ecx / paddb xmm0, xmm1MMX / SSE2 paddb is SIMD addition with separate byte elements. Scalar integer add 是对整个操作数大小的单个整数加法运算,CF 和 OF 根据寄存器的顶部确定,无论是什么。

您可以通过构造一个进位跨 8 位边界传播的测试用例来简单地证明这一点。在调试器中单步执行此操作并在添加后查看寄存器。

   mov  ax, 0x80
   add  ax, ax          ; ax = 0x0100  = 0x0080 << 1

或查看编译器输出,例如 https://godbolt.org/z/xKfK6h4d5,其中 GCC 使用 add eax, edx 来实现两个 short 变量的加法,或使用 add 的任何现有代码示例例如,做指针数学。

也许您的教授不得不自己学习汇编来教授一门课程,并且没有太多经验。 add 和其他整数寄存器操作是对整数的单一操作这一事实是非常基本的,并且在所有(?)ISA 中都是如此。 (虽然 8086 是少数具有别名到 low/high 一半的部分寄存器之一)。希望她能纠正她的误解,让 class 知道汇编是如何工作的。

But my professor said that 8086 did this operation in two steps instead of one ...

她错了:

根据8086数据sheet(第2-52页),两个16位数字相加与两个8位数字相加所用时间完全相同:3个时钟周期。

有CPUs(如8085)分两步执行16位加法;但是8086不这样做。

She said that the carry generated by lower sum won't be carried over if we used ADD instruction directly.

这意味着在添加 12FFh0001h 时,ADD BX, CX 运算结果为 1200h

完全是胡说八道

即使是Z80CPU(只有4位ALU)在这个加法中也会计算出1300h的结果;带有 16 位 ALU 的 8086(或 8088)无论如何都会计算出正确的结果!

可能她和808混淆了5:

8085 不会在 16 位加法后设置所有标志(例如零标志);然而,即使是 8085 也会计算出正确的结果并正确设置进位标志。

Is her solution the only accepted way of adding two 16-bit numbers?

在这种情况下,每个编译器都会使用 ADD BX, CX 指令。

你的教授想看看你是否了解如何使用 ADC 指令。

因此,使用ADD BX, CX并不是她想看到的。

但是,如果她没有告诉您应该只使用 8 位加法,那么您的解决方案是正确的!