x86 Procedure Bugs

Viewed 81

I've put together a program that increments from 1 to check every number under 100, if prime, the number will be stored into an array. The problem i'm getting however is that nothing is being stored into the array and the registers aren't being utilized as intended. On it's own the '_isPrime' procedure fully works as intended, but when I piece it together with the code in the main then call it thats where the errors seem to be coming from. Are my loops implemented correctly in the main? Is there anything else I should be doing in the procedure?

.DATA

arr DWORD 27 DUP (?)

.CODE           
_MainProc   PROC

        mov eax, 1      ; number in eax will be prime checked / edx will be 1 if true
J1:     
        mov edx, 0      ; clear edx 
        inc eax         ; increment eax to begin prime checking
        cmp eax, 100    ; if eax reaches 100 loop ends
        je J2
        push eax
        push edx
        call _isPrime   ; prime check on eax
        cmp  edx, 0     ; if not prime begin loop again
        je J1
        mov [arr], eax  ; if prime eax is stored into array
        jmp J1          ; loop begins again
 
J2:
      
    mov     eax, 0
    ret

_MainProc   ENDP

_isPrime PROC 

        push ebp 
        mov  ebp, esp 
        push ecx
        push ebx

        cmp     eax,1
        jle     L2
        mov     ecx,eax
        shr     ecx,1
        mov     ebx,2
        mov     edx,1
L1:
        cmp     ebx,ecx
        jg      L2
        push    eax
        mov     edx,0
        div     ebx
        cmp     edx,0
        je      L2
        inc     ebx
        jmp     L1
        mov     edx,1
L2:
                      
        pop ebx
        pop ecx
        pop ebp
        ret

_isPrime ENDP            

END   

1 Answers
   push eax
   push edx
   call _isPrime   ; prime check on eax

You don't need to supply this EDX parameter at all. The _isPrime procedure doesn't use it as an argument.
Next you need to balance the stack. You could opt to return from the proc using ret 4 to pop off the sole argument EAX provided at least that the proc fetched it with an instruction like mov eax, [ebp + 8]...

   mov [arr], eax  ; if prime eax is stored into array
   jmp J1          ; loop begins again

You will store every prime on top of the other!

    mov edi, offset arr

    ...

    mov [edi], eax
    add edi, 4
    jmp J1

This could work.


  push    eax
  mov     edx,0
  div     ebx
  cmp     edx,0
  je      L2

In _isPrime you fail to preserve the value in EAX because the pop eax is missing!

push    eax       ; (1)
xor     edx, edx
div     ebx
pop     eax       ; (1)
test    edx, edx
jz      L2

For correct operation the mov edx, 1 instruction needs to go in the loop and not before the loop:

L1:     mov     edx,1
        cmp     ebx,ecx
        jg      L2
Related