纳斯姆最大的共同除数

时间:2013-06-02 21:36:46

标签: assembly nasm greatest-common-divisor

我想写一个程序,你输入两个数字并得到最大的公约数 使用以下伪代码:

Euclid(a, b)
while (b != 0)
{
r = a mod b
a = b
b = r
}
return a

这是我当前的版本,它给出了一个错误:52:操作码和操作数的无效组合。

%include "asm_io.inc"

segment .data
prompt1 db    "Enter a number: ", 0       
prompt2 db    "Enter another number: ", 0

segment .bss
input1  resd 1
input2  resd 1

segment .text
    global  asm_main
asm_main:
    enter   0,0               ; setup routine
    pusha

    mov     eax, prompt1      
    call    print_string
    call    read_int   
    push eax       

    mov     eax, prompt2       
    call    print_string
    call    read_int    
    push eax      


    call euclid

    call print_int



    popa
    mov     eax, 0            ; return back to C
    leave                     
    ret


    ; Function euclid

    euclid:
         push ebp
         mov ebp, esp

         mov ebx, [ebp+8]
         mov ecx, [ebp+12]



         _while: 
            div ecx,ebx
            mov ebx,ecx
            mov ecx,edx
            cmp ecx,0
            jz _end
            jmp _while
         _end: 
            mov eax,ebx

        pop ebp
        ret

我对assembly和nasm完全不熟悉,我希望你能帮助我找到错误或错误的语法。

3 个答案:

答案 0 :(得分:1)

没有div ecx,ebx指令。如果您要执行ecx / ebx,那么您必须使用div r/m32形式,将edxeax形成的64位数量除以给定的操作数。因此,您必须注意将edx清零以获得32位红利(或使用符号扩展cdq指令进行签名操作)。 代码可能如下所示:

xor edx, edx
mov eax, ecx
div ebx  ; eax = ecx / ebx, remainder in edx

如有疑问,请使用instruction set reference

您的代码中可能存在逻辑错误,我只回答了您提出的问题。

答案 1 :(得分:0)

代码中的错误是您的逻辑。你应该返回'r'而不是'a',并且在'while loop'中你应该将'a mod b'的值与零而不是'b'的值进行比较。还有更多的情况是由于两个整数的比较而发生的,例如,第一个整数可以小于或大于第二个整数。在算法中也应该考虑那些比较。我根本不知道nasm或汇编,但你应该尝试下面的psudo代码。 'min(a,b)'是一个你应该编写的函数,它返回'a'和'b'的最小值。我不知道nasm或汇编的语法,但逻辑应该运行良好。一切顺利!< / p>

 Euclid(a,b)

       if(min(a,b)==a){
             while (b mod a != 0) { 
                r = b mod a
                b = a
                a = r
             }
             return r
          }

        else{
               while(a mod b!=0){
                  r = a mod b
                  a = b
                  b = r
              }
               return r
          }

答案 2 :(得分:0)

这是一个使用内联汇编计算最大公约数的程序。

#include <stdio.h>

int gcd( int a, int b ) {
    int result ;
    /* Compute Greatest Common Divisor using Euclid's Algorithm */
    __asm__ __volatile__ ( "movl %1, %%eax;"
                          "movl %2, %%ebx;"
                          "CONTD: cmpl $0, %%ebx;"
                          "je DONE;"
                          "xorl %%edx, %%edx;"
                          "idivl %%ebx;"
                          "movl %%ebx, %%eax;"
                          "movl %%edx, %%ebx;"
                          "jmp CONTD;"
                          "DONE: movl %%eax, %0;" : "=g" (result) : "g" (a), "g" (b)
                          );

    return result ;
}

int main(int argc, const char * argv[])
{
    printf("%d \n", gcd(30, 50));
    return 0;
}

我在这里找到了它,http://www.codeproject.com/Articles/15971/Using-Inline-Assembly-in-C-C