x86 程序错误

x86 Procedure Bugs

我编写了一个程序,该程序从 1 开始递增以检查每一个小于 100 的数字,如果是素数,该数字将被存储到一个数组中。然而,我遇到的问题是数组中没有存储任何内容,并且寄存器没有按预期使用。 '_isPrime' 过程本身完全按预期工作,但是当我将它与 main 中的代码拼凑在一起然后调用它时,这就是错误似乎来自的地方。我的循环是否在主体中正确实现?程序中还有什么我应该做的吗?

.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   

   push eax
   push edx
   call _isPrime   ; prime check on eax

您根本不需要提供此 EDX 参数。 _isPrime 过程不使用它作为参数。
接下来你需要平衡堆栈。您可以使用 ret 4 从 proc 中选择 return 来弹出唯一参数 EAX 至少前提是 proc 使用 mov eax, [ebp + 8]...

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

您会将每个质数存储在另一个之上!

    mov edi, offset arr

    ...

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

这可行。


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

_isPrime 中,您无法保留 EAX 中的值,因为缺少 pop eax

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

为了正确操作,mov edx, 1 指令需要进入 in 循环而不是 before 循环:

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