欧几里德GCD语言汇编。代码无效

时间:2014-10-30 20:09:18

标签: visual-studio x86

我在语言汇编中写这个欧几里得GCD程序,我想我知道问题是什么,但我不知道如何修复它。问题是我从内部递归地调用GCD,每次调用GCD时,ESP都会向下移动4个字节,因为它必须在每次调用时将返回地址存储在堆栈中。因此,我的EBP将指向前一次调用的4个字节。有人可以帮我解决这个问题吗?

;Kirtan Patel
;Create a Euclidian GCD Program
;10/30/2014

.586

.MODEL FLAT

.STACK 4096

.DATA
numberm DWORD 14
numbern DWORD 10
.CODE
main PROC
         push numbern ;push 10 onto the stack
         push numberm ;push 14 onto the stack
         call gcd     ; call gcd function
         add esp, 8   ;pop off the parameters from the stack.
         ret          ;exit the program
main ENDP

gcd PROC
        push ebp      ;push ebp onto the stack to preserve previous contents of ebp 
        mov ebp, esp  ;copy esp to ebp to access the parameters 10 and 14 later on
        push edx      ;save the registers 
        push ebx
        push ecx
        mov ecx, DWORD PTR[ebp+12] ;copy 10 to ecx
        cmp ecx, 0                 ;compare to see if the divisor is zero
        jnz recur                  ;if it is not zero then recursively call gcd
        mov eax, DWORD PTR[ebp+8]  ; if it zero then copy 14 to eax and return
        pop ecx                    ;restore the contents of registers before exiting the function
        pop ebx
        pop edx
        pop ebp
        ret
recur: mov eax, DWORD PTR[ebp+8]   ;copy 14 to eax
       cdq                         ; prepare the edx register for division to store the remainder
       div ecx                     ;eax/ecx (14/10)
       mov DWORD PTR[ebp+12], edx  ;copy the remainder into numbern on the stack
       mov DWORD PTR[ebp+8], ecx   ;copy the new divisor into numberm on the stack
       pop ecx                     ;restore registers
       pop ebx
       pop edx
       pop ebp
       call gcd                    ;recursively call gcd

gcd ENDP


END

1 个答案:

答案 0 :(得分:0)

您可以在堆栈上传递参数。使用this C program作为递归函数的原型,并使用described here技术在每次递归调用时传递参数。

int findgcd(int x,int y){
     while(x!=y){
          if(x>y)
              return findgcd(x-y,y);
          else
             return findgcd(x,y-x);
     }
     return x;
}