【问题标题】:Finding GCD of an array of n numbers in assembly without external variables在没有外部变量的汇编中查找n个数组的GCD
【发布时间】:2019-05-14 11:03:05
【问题描述】:

我有一个关于在汇编中查找包含 n 个数字的数组的 GCD(我在 Visual Studio 2017 中使用 asm)而不在 C 中使用外部变量的作业。我得到的唯一变量是n 个数字的数组。 我在找到数组的前两个数字的 GCD 时没有问题,但我不确定如何创建一个循环,在这个循环中我不断用数组的下一个数字更新我的寄存器,因为 GCD 是 3 个数字,b,c 是 GCD(GCD(a,b),c)。我希望能得到一些帮助。

#include <stdio.h>

void main()
{
    unsigned int intArray[] = {12,24,3};
    int num = sizeof(intArray) / sizeof(intArray[0]);
    unsigned int MCD;

    __asm
    {
        xor ebx,ebx
        xor edx,edx
        xor eax,eax
        mov eax, intArray[0]
        mov ebx, intArray[1]
        jmp major

    zerob:
        mov MCD, eax
        jmp fine

    major:
        cmp eax,ebx
        jg nextstep
        xchg eax,ebx
        jmp major

    nextstep:
        cmp ebx,0
        je zerob
        jne modulus

    modulus:
        div ebx
        mov MCD,edx
        mov eax,ebx
        mov ebx,MCD
        jmp nextstep

    fine:

    }

    printf("M.C.D.: %d \n", MCD);
    getchar();
}

【问题讨论】:

  • 不清楚您的问题是什么。计算前两个数字的 GCD,然后继续计算中间结果和数组中下一个数字的 GCD。
  • 我必须找到一个数组的 n 个数字的 GCD。我写的代码找到了两个数字的GCD,不知道如何扩展这段代码来实现数组所有数字的GCD。
  • 如果eax == ebx,这可能会卡在major 中的无限循环中。你将永远交换它们,因为a&gt;b 是假的,b&gt;a 也是如此。从那里删除jmp major;最多需要一个xchg,所以你只需要有条件地跳过xchg
  • 无论如何,围绕它放置另一个循环,它会推进一个指针并加载下一个元素,用下一个输入替换 EBX。您仍然在 EAX 中获得 GCD 结果,因此您再次有 2 个输入,您的代码需要它们。
  • 你能写出它的代码吗?我能够理解这一点,但由于我是编程汇编的初学者,我无法正确编写它。如果你能明确地向我展示这将非常有帮助。顺便说一句,提前谢谢!

标签: assembly x86 greatest-common-divisor


【解决方案1】:

第 1 步,清理和更正

删除冗余指令,重新安排代码以减少跳转,如果使用 2 个相同的数字,则删除潜在的无限循环,并在每次除法之前将 EDX 归零:

    mov  eax, intArray[0]
    mov  ebx, intArray[1]

major:
    cmp  eax, ebx
    jg   nextstep
    xchg eax, ebx
nextstep:
    cmp  ebx, 0
    je   zerob
modulus:
    xor  edx, edx
    div  ebx
    mov  eax, ebx
    mov  ebx, edx
    jmp  nextstep

zerob:
    mov  MCD, eax
fine:

第二步,创建循环

使用num中的元素个数,通过ESI中的指针获取数字并将内循环变成DO-WHILE循环(有条件地跳转到顶部):

    mov  ecx, num       ;Number of elements
    lea  esi, intArray[0]
    lodsd               ;First number in array
    dec  ecx
    jz   DONE

AGAIN:
    mov  ebx, [esi]     ;Next number in array
    add  esi, 4

major:
    cmp  eax, ebx
    jg   nextstep
    xchg eax, ebx
    jmp  nextstep
modulus:                ;Inner loop
    xor  edx, edx
    div  ebx
    mov  eax, ebx
    mov  ebx, edx
nextstep:
    test ebx, ebx
    jnz  modulus

    dec  ecx
    jnz  AGAIN

DONE:
    mov  MCD, eax
fine:

【讨论】:

    猜你喜欢
    • 2020-03-13
    • 2016-03-06
    • 1970-01-01
    • 1970-01-01
    • 2016-09-05
    • 1970-01-01
    • 2021-05-03
    • 1970-01-01
    • 2020-05-25
    相关资源
    最近更新 更多