Can anybody tell me how to EBP in greatest common factor program.
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
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
the PUSH EAX is killing you, as you have no POP to balance the stack
give me a few minutes.....
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
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
it is greatest common divisor. for e.g. gcd(36,90)=18 where n=36 and m=90.
Thankyou dedndave for helping me out. but there is a problem after i ran it.
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
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
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
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.
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
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 ?
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
Quote from: dedndave on April 14, 2011, 05:40:23 PM
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
I got EAX=0 :wink
assemble as console app
INCLUDE \masm32\include\masm32rt.inc
.CODE
_main PROC
push 90
push 36
call GCD
print ustr$(eax),13,10
inkey
exit
_main ENDP
;-------------------------------------------------------------------
GCD PROC
push ebp
mov ebp,esp
mov ecx,[ebp+12] ; get m
mov eax,[ebp+8] ; get n
or ecx,ecx
jz G1
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 GCD
G1: pop ebp
ret 8 ; clean up stack
GCD ENDP
;-------------------------------------------------------------------
END _main
supposedly, m must be greater than n, but i get the same result either way - lol
common people - these is all wikipedia stuff :bg
non-recursive:
Quotegcd proc uses ebx a:DWORD,b:DWORD
mov eax,a
mov ecx,b
.while ecx
mov ebx,ecx
xor edx,edx
div ecx
mov ecx,edx
mov eax,ebx
.endw
ret
gcd endp
yah - i got that
but, he wanted a recursive version :P
the non-recursive version is much faster, i am sure
and - i could speed up the recursive code by not using EBP but that doesn't matter
if i wanted the function, i would use a loop, too
sorry i called the old LCF
qword,
we dont need to use EBX
gcd1 proc m:DWORD, n:DWORD
mov eax, m
mov ecx, n
.while ecx
xor edx, edx
div ecx
mov eax, ecx
mov ecx, edx
.endw
ret
gcd1 endp