As 8086 has a 16-bit ALU with 16-bit registers, this is how I pictured adding two 16-bit numbers:
MOV BX,12FFh
MOV CX,0001h
ADD BX,CX
But my professor said that 8086 did this operation in two steps instead of one by adding the numbers in pairs of 8-bit numbers. She said that the carry generated by lower sum won't be carried over if we used ADD instruction directly. This is how she solved it:
MOV BX,12FFh
MOV CX,0001h
ADD BL,CL
ADC BH,CH
Is her solution the only accepted way of adding two 16-bit numbers?
Your first code block produces identical results in BX to your second code block. (And in CF and SF, and I think OF. Not ZF, PF, or AF, though, for obvious reasons.)
16-bit add
is not SIMD addition of two separate byte adds. If you want that, use movd xmm0, ebx
/ movd xmm1, ecx
/ paddb xmm0, xmm1
. MMX / SSE2 paddb
is SIMD addition with separate byte elements. Scalar integer add
is a single integer addition operation on the entire operand-size, with CF and OF determined according to the top of the register, whatever that is.
You can trivially prove this by constructing a test case where carry propagates across the 8-bit boundary. Single-step this in a debugger and look at registers after the add.
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.
Perhaps your professor has had to learn assembly herself to teach a course, and doesn't have much experience with it. The fact that add
and other integer-register operations are single operations on the whole number is pretty fundamental, and is like that across all(?) ISAs. (Although 8086 is one of the few with partial registers that alias onto low/high halves). Hopefully she can correct her misunderstanding and let the class know how assembly works.