Hi so I'm having problem with my Assembly project. I am supposed to print out x prime numbers in order. But I cannot use the fuction USES. When I tried to remove it, I got an infinite loop. Can someone please help me, thank you
isPrime PROC USES ECX EBX
; Checks whether a number is prime or not. If given number is prime, returns
; boolean value 1. Otherwise, returns 0.
; receives: A number in EAX
; returns: boolean value(0 or 1) in EAX
; preconditions: eax is in [1..200]
; registers changed: eax, ebx, ecx, edx
;-------------------------------------------------------------------------
mov ecx,eax ; copy the number p into ECX
mov esi, 2 ; i=2
startLoop:
cmp esi,ecx
jge PrimeNum ; if i>=p, p is prime and goto PrimeNum
mov edx,0
mov eax,ecx
div esi ; calculate p/i. EAX=p/i and EDX=p%i
cmp edx, 0
je NotPrime ; if remainder = 0, p is not prime
inc esi ; otherwise, continue search
jmp startLoop
PrimeNum:
mov eax, TRUE ; if p is prime , return true
ret
NotPrime:
mov eax, FALSE ; if p is not prime, return true
ret
isPrime ENDP
When I removed the USES part
mov ecx,eax ; copy the number p into ECX
mov try2, 2 ; i=2
startLoop:
cmp try2,ecx
jge PrimeNum ; if i>=p, p is prime and goto PrimeNum
mov edx,0
mov eax,ecx
div try2 ; calculate p/i. EAX=p/i and EDX=p%i
cmp edx, 0
je NotPrime ; if remainder = 0, p is not prime
inc try2 ; otherwise, continue search
jmp startLoop
PrimeNum:
mov eax, TRUE ; if p is prime , return true
ret
NotPrime:
mov eax, FALSE ; if p is not prime, return true
ret
isPrime PROC USES ECX EBX
Although this claims to be using EBX, the code actually uses ESI and doesn't even touch EBX.
If you don't want to rely on USES
, you'll need to preserve the registers that you want to keep or that need preserving. Because your code has multiple ret
instructions, you also need multiple restoration sequences:
isPrime PROC
push ecx ;
push edx ; Preserves ECX EDX ESI
push esi ;
mov ecx, eax ; copy the number p into ECX
mov esi, 2 ; i=2
startLoop:
cmp esi, ecx
jge PrimeNum ; if i>=p, p is prime and goto PrimeNum
mov edx, 0
mov eax, ecx
div esi ; calculate p/i. EAX=p/i and EDX=p%i
cmp edx, 0
je NotPrime ; if remainder = 0, p is not prime
inc esi ; otherwise, continue search
jmp startLoop
PrimeNum:
mov eax, TRUE ; if p is prime , return true
pop esi ;
pop edx ; Restores ESI EDX ECX
pop ecx ;
ret
NotPrime:
mov eax, FALSE ; if p is not prime, return true
pop esi ;
pop edx ; Restores ESI EDX ECX
pop ecx ;
ret
isPrime ENDP
It would be easy to avoid this double ret
:
isPrime PROC
push ecx ;
push edx ; Preserves ECX EDX ESI
push esi ;
mov ecx, eax ; copy the number p into ECX
mov esi, 2 ; i=2
startLoop:
mov eax, TRUE ; if p is prime , return true
cmp esi, ecx
jge PrimeNum ; if i>=p, p is prime and goto PrimeNum
mov edx, 0
mov eax, ecx
div esi ; calculate p/i. EAX=p/i and EDX=p%i
cmp edx, 0
je NotPrime ; if remainder = 0, p is not prime
inc esi ; otherwise, continue search
jmp startLoop
NotPrime:
mov eax, FALSE ; if p is not prime, return true
PrimeNum:
pop esi ;
pop edx ; Restores ESI EDX ECX
pop ecx ;
ret
isPrime ENDP
This code is still not optimal for checking primality. You can find more ideas about a fast check for primality in this answer