如何编写最大的常见除数程序是80x86汇编?

时间:2014-04-23 20:45:30

标签: loops assembly x86 greatest-common-divisor

我知道找到两个数字的gcd有不同的方法,但是我想知道哪个最好给出程序集的命令以及如何将该方法实现到程序中?

这是我到目前为止所拥有的:

.586
.MODEL FLAT

INCLUDE io.h            ; header file for input/output

.STACK 4096

.DATA
number1 DWORD ?
number2 DWORD ?
prompt1 BYTE "Please enter an integer for X", 0
prompt2 BYTE "Please enter an integer for Y", 0
string BYTE 40 DUP (?)
resultLbl BYTE "The greatest common divisor of X and Y is", 0
gcd BYTE 11 DUP (?), 0

.CODE
_MainProc PROC
    input prompt1, string, 40
    atod string
    mov number1, eax

    input prompt2, string, 40
    atod string
    mov number2, edx

    mov eax, number1
    mov edx, number2

Get_GCD:
    xchg eax,edx
    cmp eax,edx
    jb Get_GCD
    sub eax,edx
    test edx,edx
    jnz Get_GCD
    ret

    dtoa gcd, edx
    output resultLbl, gcd

    mov eax, 0
    mov edx, 0
    ret
_MainProc ENDP
END                             ; end of source code

我跑了,没有任何反应。

3 个答案:

答案 0 :(得分:0)

删除jnz Get_GCD之后和dtoa之前的ret。欧几里德减法算法循环可以缩短:

;                                       ;eax and edx are the numbers
gcd0:   cmp     edx,eax                 ;edx = smaller number
        jb      gcd1
        xchg    eax,edx
gcd1:   sub     eax,edx                 ;subtract smaller from larger
        jnz     gcd0                    ;loop if not done
;                                       ;edx = gcd

请注意,上述循环的最坏情况是eax = 0xffffffff和edx = 1,需要40亿个循环才能完成。下面所示的欧几里德模数算法使用除法,但最坏情况下的循环数n是:n <= 5 log10(较小的数字)或n <= 1.50515 log2(较小的数字)。对于32位无符号整数,最坏的情况是两个斐波那契数,1836311903和2971215073(gcd = 1),其中循环数= 45,其中&lt; = 5 log10(1836311903)(〜= 46.32)。

Euclid模数法:

;                                       ;eax and ebx are the numbers
        cmp     ebx,eax                 ;ebx = smaller number
        jb      gcd0
        xchg    eax,ebx
gcd0:   xor     edx,edx                 ;divide: larger / smaller
        div     ebx
        mov     eax,ebx                 ;eax = new larger (was smaller)
        mov     ebx,edx                 ;ebx = new smaller (new remainder)
        or      ebx,ebx                 ;loop if new smaller != 0
        jnz     gcd0
;                                       ;eax = gcd

答案 1 :(得分:-1)

include Irvine32.inc

    .data

factor  DWORD 60
i       DWORD 2
largest DWORD ?

str1    BYTE "Greatest common factor",0

    .code 
    main PROC

top:    
    mov eax,factor
    mov ebx,i
    xor edx,edx
    div ebx
    call writedec
    cmp ebx,eax
    je L2
    call crlf
    cmp eax,factor
    jb L1
    inc i
    jmp top
L1:
    mov largest,ebx    
L2:
    mov eax,largest
    mov edx,OFFSET str1
    call writestring
    call writedec

    exit

    main ENDP
    END main

答案 2 :(得分:-2)

Get_GCD:
    xchg EAX,EDX
    cmp EAX,EDX
    jb Get_GCD
    sub EAX,EDX
    test EDX,EDX
    jnz Get_GCD
    ret