首页 > 解决方案 > 两个整数的最大公约数 (GCD) 是汇编语言中将两个整数均分的最大整数

问题描述

这是问题:

两个整数的最大公约数 (GCD) 是将两个整数均分的最大整数。GCD 算法涉及循环中的整数除法,由以下 C++ 代码描述:

int GCD(int x, int y)
{
x = abs(x); // absolute value
y = abs(y);
do {
int n = x % y;
x = y;
y = n;
} while (y > 0);
return x;
}

用汇编语言实现这个函数并编写一个测试程序,多次调用这个函数,传递不同的值。在屏幕上显示所有结果。

这是我正在尝试的汇编语言代码:

INCLUDE Irvine32.inc

.data
array SDWORD -4,-20,36,24,11,9,448,224,15,-30
str1 BYTE "Greatest common divisor is: ",0

.code
main PROC

    mov  ecx,LENGTHOF array / 2
    mov  esi,OFFSET array

L1: mov  eax,[esi]
    mov  ebx,[esi+4]
    call findGCD
    mov  edx,OFFSET str1
    call WriteString
    call WriteDec
    call Crlf
    add  esi,TYPE array * 2
    loop L1

    exit
main ENDP
 
findGCD PROC

    push ebx
    push edx

    .IF SDWORD PTR eax < 0
      neg eax
    .ENDIF

    .IF SDWORD PTR ebx < 0
      neg ebx
    .ENDIF

L1: mov  edx,0
    div  ebx
    cmp  edx,0
    je   L2
    mov  eax,ebx
    mov  ebx,edx
    jmp  L1

L2: mov eax,ebx ; EAX = GCD

    pop edx
    pop ebx
    ret
findGCD ENDP

END main

标签: assemblyx86masmgreatest-common-divisor

解决方案


您有两个具有相同名称的标签,即两个L1标签。除非您为标签指定不同的名称,否则您无法组装它。

第二个L1标签是一个循环,它将继续循环直到余数为零。您可以将其重命名为有用的名称,以便您的代码易于阅读/理解:

WhileRemNotZero:
    mov  edx,0
    div  ebx
    cmp  edx,0
    je   L2
    mov  eax,ebx
    mov  ebx,edx
    jmp  WhileRemNotZero

您的其余代码都很好。它将为每 2 个数字打印以下内容(imo 不是一个很好的方法):

Greatest common divisor is: 2 //just a number, don't take it as actual result

就个人而言,我只会计算整个数组的 GCD,然后只打印一次结果。


推荐阅读