News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

How EBP works.

Started by xerox, April 14, 2011, 03:38:25 PM

Previous topic - Next topic

xerox

Can anybody tell me how to EBP in greatest common factor program.

dedndave

your other thread wasn't too bad
it was how you worded it that made Hutch cough - lol
the title "can you fix this code" was a bad start

if you had titled the thread "Lowest Common Denominator"
and simply stated, "i can't figure out what i am doing wrong"
you would have gotten a better response
from what i can see, you made a good effort to get going, and are just having a little problem

at first glance, your use of EBP in that code looked ok
your problem may be elsewhere - i really didn't look too closely

anyways, the EBP register is used to hold an address on the stack that we call a "stack frame"
in each recursion, there will be a different frame address
that way, each recursion can have a different set of local variables

xerox

thank you dedndave,I apologize for that one  i tried to say something but went to say something.

i am going to post my code can you help me out please


LCF PROC
   push ebp
   mov  ebp,esp
   
   mov eax,8[ebp]   ; get n
   cmp  eax,0      ; n < 0?
   jne   L1         ; yes: continue

; Base Case
   mov ebx,12[ebp]
   jmp L2
L1:   
     push eax
   mov ebx,12[ebp]          ; get m
   mov edx,0         ; prepare for division

   div ebx           ; n/m
   push edx         ; push m
   ;push eax         ; push n as remainder
   call LCF

; Instructions from this point on execute when each
; recursive call returns.
L2:

   
   pop ebp
   ret 8         ; clean up stack

         
LCF ENDP

dedndave

the PUSH EAX is killing you, as you have no POP to balance the stack
give me a few minutes.....

RuiLoureiro

xerox,
        Do you want to get «greatest common factor» btw m and n ?
        If m=90 and n=30 then you want to get 30, yes ?
        Is it ? Give an example

dedndave

i think i see the problem
when you use DIV, the quotient will be in EAX, the remainder will be in EDX
you have the PUSH's swapped   :P
see if this works...

LCF     PROC

        push    ebp
        mov     ebp,esp
        mov     eax,[ebp+8]   ; get n
        mov     ebx,[ebp+12]  ; get m
        or      eax,eax       ; n = 0?
        jz      L1            ; yes: exit

        xor     edx,edx       ; prepare for division
        div     ebx           ; n/m
        push    eax           ; push m
        push    edx           ; push remainder as n
        call    LCF

L1:     pop     ebp
        ret     8             ; clean up stack

LCF     ENDP


i did a little cleanup - lol

xerox

it is greatest common divisor. for e.g. gcd(36,90)=18 where n=36 and m=90.

xerox

Thankyou dedndave for helping me out. but there is a problem after i ran it.

dedndave

yah - it isn't quite right, yet
i had to write some code to test it

here is the algo in C, non-recursive loop
/* a & b are the numbers whose GCD is to be found.
Given a > b
*/
  int gcd(int a,int b)
  {
    int c;
    while(1)
    {
  c = a%b;
  if(c==0)
    return b;
  a = b;
  b = c;
    }
  }

we need to test the remainder for 0 after division

RuiLoureiro

Quote from: xerox on April 14, 2011, 04:46:51 PM
it is greatest common divisor. for e.g. gcd(36,90)=18 where n=36 and m=90.

        If you start with gcd=n (36) then
    a)  divide m (90) by gcd
    b)  If remainder not zero gcd=gcd-1 try again - goto a)
        If zero divide n (36) by gcd. If remainder not zero goto b)
         If zero we have the gcd

dedndave

you were close - lol
LCF     PROC

;returns the greatest common denominator in EAX

        push    ebp
        mov     ebp,esp
        mov     ecx,[ebp+12]  ; get m
        mov     eax,[ebp+8]   ; get n
        or      ecx,ecx
        jz      L1

        xor     edx,edx       ; prepare for division
        div     ecx           ; n\m
        push    edx           ; push new remainder as new m
        push    ecx           ; push old remainder as new n
        call    LCF

L1:     pop     ebp
        ret     8             ; clean up stack

LCF     ENDP


notice that i use ECX rather than EBX
that has no effect on the routine, other than EBX is typically a preserved register in win 32

the PROC name is a little confusing - it should be GCD
LCF refers to the lowest common factor

xerox

Thank you dedndave. you are so helpful for me I really appreciated. I have a final question and  quick question about assembly language. I am done with it.
  or      ecx,ecx
and
  xor    edx,edx

what these things do.

dedndave

oh
OR ECX,ECX or TEST ECX,ECX are shorter, quicker tests for 0
CMP ECX,0 is larger

XOR EDX,EDX or SUB EDX,EDX are similar shortcuts for zeroing a register, although they alter the flags
in this case, we do not care what the flags are

RuiLoureiro

dedndave,
            LFC returns the greatest common denominator in EAX ?

            So if we call         
           
            push       36
            push       90
            call       LCF
           
            we have EAX =18 no ? Is this ?

dedndave

it is the greatest common denominator
not the least common factor
in spite of the name he gave the routine,
you had to have read the text that was deleted from his original thread
that's how i knew what he was after   :P