0

I want to write a program where you enter two numbers and get the Greatest common divisor with the following pseudo code:

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

THis is my current version which gives me an error:52:invalid combination of opcode and operands.

%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

I am totally new to assembly and nasm and i hope you can help me to find the error or false syntax.

4

3 回答 3

1

没有div ecx,ebx指示。如果你想执行ecx/ebx那么你必须使用div r/m32将 64 位数量除以给edxeax操作数的形式。因此,您必须注意将edx32 位被除数归零(或使用符号扩展cdq指令进行有符号操作)。代码可能如下所示:

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

如有疑问,请使用指令集参考

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

于 2013-06-03T20:27:56.820 回答
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-CC

于 2013-12-27T23:30:43.727 回答
0

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

 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
          }
于 2013-08-04T18:47:48.460 回答