Combining the result of 16-bit * 16-bit multiplication to output a 32-bit value

65 Views Asked by At
 mov ax, [integerOp1]
    mul [integerOp2]
    
    mov resultHi, dx
    mov resultLo, ax
    
     ;Integer -> ASCII
    
    
    mov cx, 0       ; Count for digits in result
    @IterateMulLo:       
    cwd             ; Preventing Division Overflow
    mov bx, 10
    
    div bx          ; Dividing by 10 to get the digits of result as remainder
    
    mov dh, 00h     ; Clearing dh so dx conatins just the digit
    
    add dl, 30h     ; Converting digit in dl to ASCII
    
    push dx         ; Pushing the ASCII to stack
    
    inc cx          ; Increment digit count 
    
    cmp ax, 0       ; Repeating process until quoteint reaches 0. i.e: no more digits left
    jg @IterateMulLo
    
    mov digitCount, cx  
    
    mov ax, resultHi
    @IterateMulHi:       
    cwd             ; Preventing Division Overflow
    mov bx, 10
    
    div bx          ; Dividing by 10 to get the digits of result as remainder
    
    mov dh, 00h     ; Clearing dh so dx conatins just the digit
    
    add dl, 30h     ; Converting digit in dl to ASCII
    
    push dx         ; Pushing the ASCII to stack
    
    inc cx          ; Increment digit count 
    
    cmp ax, 0       ; Repeating process until quoteint reaches 0. i.e: no more digits left
    jg @IterateMulHi
    
    mov digitCount, cx
    
    jmp @Result

This is the code that I'm using for multiplication of two 16 bit numbers in emu 8086. The multiplication mul [integerOp2] stores the result in DX (Hi word) and AX (Lo word). If we take the example of 1234 * 1234 (decimal). The value in DX is 0017 and the value in AX is 3C44 (hex). The values in the register when combined result in 00173C44 (hex) = 1,522,756 (Decimal), which is the right result. However I'm pushing each of these values separately to the stack and then popping to display the result gives me 2315428 which is DX = 0017 (hex) = 23 and AX = 3C44 (hex) = 15428 (decimal).
So by dealing with these values separately while outputting the result shows the incorrect answer. How would I combine the lo and hi words for outputting the right result?

1

There are 1 best solutions below

0
Sep Roland On

A detailed explanation for displaying the 32-bit value in DX:AX can be found in Displaying numbers with DOS.

So, although your question is a duplicate, please read the following about your present 16-bit conversion:

cwd             ; Preventing Division Overflow

Prior to using the div bx instruction you should not use cwd. It is perfectly possible for AX to contain a value in the range 32768 to 65535. Applying cwd would then fill DX with FFFFh, and it would produce a wrong result! Always write xor dx, dx.

mov bx, 10

The value in BX doesn't change while the loop runs, so better keep it outside of the loop. Put it just above @IterateMulLo:.

mov dh, 00h     ; Clearing dh so dx conatins just the digit

This is a redundant instruction. After the division by 10, the whole DX register contains a value in the range 0 to 9. DH is 0 for sure.

cmp ax, 0       ; Repeating process until quoteint reaches 0. i.e: no more digits left
jg @IterateMulLo

This is correct, but the usual way to write it, is to test AX with itself and branch on the NonZero condition. And this has a one byte shorter encoding too.

test ax, ax
jnz  @IterateMulLo