Search code examples
assemblyrecursionmasmgreatest-common-divisorirvine32

GCD recursive assembly language X86 MASM


Thank everyone for the help I have made some really good changes but now it gives me an answer of +4198498 instead of 5 for the first set of values which I know is wrong. Did i push something wrong or did not pop a reg correctly? I cleaned up the stack right by using the ret 8 which should clean up the stack for the next call is that right?

Here is what I have so far:

TITLE MASM GCD                      (GCD.asm)


; Description:GCD recursive
; 
; Revision date:

INCLUDE Irvine32.inc
.data
myMessage BYTE "Assignment 7 GCD Recursive style",0dh,0ah,0
myMess2   BYTE "GCD = " ,0dh,0ah,0


;first set of nums
val1 DWORD  5
val2 DWORD  20

;second set of nums
val3 DWORD  24
val4 DWORD  18

;3rd set
val5 DWORD  11
val6 DWORD  7

;4th set
val7 DWORD  432
val8 DWORD  226

;5th set
val9 DWORD  26
val10 DWORD  13

.code
main PROC
    call Clrscr  

    mov  edx,offset myMessage
    call WriteString        ;write message
    call Crlf               ;new line
    push val1
    push val2
    call GCD

    exit
main ENDP

;------------------------------------------------
GCD PROC,
; This finds GCD
; Gets values from stored values
;returns NA

;------------------------------------------------

        xor edx,edx
        mov eax,dword ptr[esp+8] ;dividend
        mov ebx,dword ptr[esp+4] ;divisor
        div ebx              ;eax/ebx
        cmp  edx,0           ;remainder in edx
        je   L1              ;yes: quit
        call GCD             ;no: call GCD agian
    L1:
        mov eax,ebx          ;move the divisor into eax for printing i.e GCD    
        mov  edx,offset myMess2
        call WriteString
        call WriteInt        ;Display GCD WriteInt uses EAX = qutent
        call crlf
        ret 8                ;clean up the stack
GCD ENDP

END main

Solution

  • First I see a few errors and bad habits:

    GCD PROC,
        dividend:DWORD,
        divisor:DWORD
    

    Declaring local variables for your procedures is a bad habit in my opinion. (result from high level languages)

    You need to put that in your data segment. Additionally there's a syntax error, the dwords are uninitialized thus you should declare them like this:

    .DATA ?
    dividend  dword ?
    divisor dword ?
    

    You also have a problem with the registers for the div instruction:

    xor edx,edx
    mov eax,xxx ;dividend
    mov ebx,yyy ;divisor
    div ebx     ;eax/ebx
    cmp  edx,0  ;remainder in edx
    

    Now to use your sets of values and divide them you ave different choices:

    1-move them manually 1 by 1 in your registers

    mov eax,dword ptr[val01] ;dividend
    mov ebx,dword ptr[val02] ;divisor
    

    2-you push them directly on the stack (like function parameters)

    push val01
    push val02
    call GDC
    
    ;in GDC proc
    mov eax,dword ptr[esp+8]
    mov ebx,dword ptr[esp+4]
    

    3-put them in an "array" and loop through them

    exercise for you