我必须找到 3 个无符号 16 位数字的 gcd。它运行但不提供正确的输出。我的代码有什么问题?

I have to find the gcd of 3 unsigned 16 bit numbers. It runs but does not give the proper output. What can be wrong in my code?

这是一个汇编语言 8086 程序,用于查找三个无符号 16 位数字的 gcd。

我检查了几次代码,我觉得这应该是正确的。

它运行并且既不给出错误也不给出警告,但它以不同的符号(如笑脸、箭头和所有符号)给出输出。

我不知道下一步该做什么。

.model small
.stack 100h
.data
        arr DW 4800h,1600h,3200h
        gcd DW ?

.code
        main proc
                mov ax,@data
                mov ds,ax

                mov cx,0
                mov si,offset arr
                mov bx,[si]
                jmp L1

        L1:

                inc si
                inc cx
                mov ax,[si]

                jmp compare

       compare:

                cmp ax,bx
                jg up1
                jb excg
        up1:


                aad
                div bx
                cmp dx,0000h
                je exit
                jmp up2


       excg:
               xchg ax,bx
               jmp up1
       up2:

                mov ax,bx
                mov bx,dx
                mov dx,0
                jmp up1
       exit:
                mov gcd,bx
                cmp cx,2
                jne L1
        je display

      display:         


                mov dx,bx
                mov ah,2
                int 21h

                mov ax,4c00h
                int 21h

                main endp

     end main

This is a assembly language 8086 program to find the gcd of three unsigned 16 bits number.

您正在尝试实现 Euclid's algorithm,但您的代码被证明是混乱和错误的。

。指针 SI 必须递增 2,因为您正在处理单词。
. aad 指令实际上应该是 cwd 指令。
. jmp compareje display 指令完全是多余的 (*)。
.单字符输出功能不足以显示 16 位数字。 检查 "Displaying numbers with DOS" 以了解如何显示结果。

这是我的程序版本。您会认出您所写的大部分内容,但顺序会更好更正确...

  mov   ax, @data
  mov   ds, ax
  mov   cx, 2
  mov   si, offset arr
  lodsw
  mov   bx, ax
next:
  lodsw
  cmp   bx, ax      ;We want to divide the bigger number by the smaller one
  jb    divide
  xchg  bx, ax
  jmp   divide
repeat:
  mov   ax, bx
  mov   bx, dx
divide:
  xor   dx, dx      ;Zero DX
  div   bx
  test  dx, dx      ;Test if DX is zero
  jnz   repeat
  dec   cx
  jnz   next
  ; the GCD is in BX at this point
  ; use the above link to "Displaying numbers with DOS" to show the result.

以多做 1 个除法为代价,可以避免预先对数字进行排序。第一师将为您建立正确的顺序。此外,第一师只有 额外 一半的时间(平均)。
这反过来又可以很容易地简化代码中的跳转。少跳来跳去总是一件好事 (*)。
此外,我没有使用 CX,因为我也可以基于 SI 进行迭代。为什么要浪费一个好的寄存器?

  mov   ax, @data
  mov   ds, ax
  mov   si, offset arr
  mov   dx, [si]
next:
  add   si, 2
  mov   bx, [si]
repeat:
  mov   ax, bx
  mov   bx, dx
  xor   dx, dx
  div   bx
  test  dx, dx
  jnz   repeat
  mov   dx, bx
  cmp   si, offset arr+4    ;End of the array minus 2
  jb    next
  ; the GCD is in BX (and also in DX) at this point
  ; use the above link to "Displaying numbers with DOS" (it's really good!) to show the result.