繁体   English   中英

我们不能用 ADD 指令在 8086 中将两个 16 位数字相加吗?

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

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

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

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

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 movd xmm1, ecx / paddb xmm0, xmm1 MMX / SSE2 paddb是带有单独字节元素的 SIMD 加法。 标量 integer add是对整个操作数大小的单个 integer 加法运算,CF 和 OF 根据寄存器的顶部确定,无论是什么。

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

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

Or look at compiler output, like https://godbolt.org/z/xKfK6h4d5 where GCC uses add eax, edx to implement addition of two short variables, or any existing examples of code using add to do pointer math, for example.

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

但是我的教授说8086做这个操作是分两步而不是一步...

她错了:

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

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

她说如果我们直接使用ADD指令,小和产生的进位不会被结转。

这意味着添加12FFh0001hADD BX, CX操作会导致1200h

这完全是胡说八道

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

也许她对 808 5感到困惑:

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

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM