![](/img/trans.png)
[英]How can I add two 16 bit numbers in assembly language in microprocessor 8086
[英]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指令,小和产生的进位不会被结转。
这意味着添加12FFh
和0001h
时ADD 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.