Assembly 主要查找-某些数组值被覆盖?

Assembly 主要查找-某些数组值被覆盖?,assembly,x86,masm,Assembly,X86,Masm,我已经写了一个Eratosthenes算法的筛子,但我有一个奇怪的错误,我不能弄清楚。(编者按:这不是一个筛子;它使用试除法来测试每个数字是否为素数。) 该程序要求用户输入一个数字,然后程序将该素数输出到屏幕程序正确打印所有素数,11之后除外,在11之后,程序将打印3个垃圾号并跳过数字13,然后从17开始继续使用正确的素数。下面是20个素数的输出示例 > Enter number of primes: 20.... prime number: 1 prime numb

我已经写了一个Eratosthenes算法的筛子,但我有一个奇怪的错误,我不能弄清楚。(编者按:这不是一个筛子;它使用试除法来测试每个数字是否为素数。)

该程序要求用户输入一个数字,然后程序将该素数输出到屏幕程序正确打印所有素数,11之后除外,在11之后,程序将打印3个垃圾号并跳过数字13,然后从17开始继续使用正确的素数。下面是20个素数的输出示例

> Enter number of primes:
20....
prime number:            1
prime number:            2
prime number:            3
prime number:            5
prime number:            7
prime number:           11
prime number:    538976288
prime number:    909588792
prime number:      3291447
prime number:           17
prime number:           19
prime number:           23
prime number:           29
prime number:           31
prime number:           37
prime number:           41
prime number:           43
prime number:           47
prime number:           53
prime number:           59
这些数字存储在一个数组中,在sieve.asm中,我放置了一个名为“PrintLoop2”的标签,用于查看数组中的每个值,我可以看到其中列出了13个,并且没有垃圾,因此我不确定为什么会发生这种情况

asm是主程序,genprimes.asm创建素数并将它们放在堆栈上,其他文件用于I/O


sieve.asm:

.586
.MODEL FLAT
INCLUDE io.h
EXTERN GenPrimes2:PROC
PUBLIC genPrimes
.STACK 4096                 ; reserve 4096-byte stack
.DATA                       ; reserve storage for data

count    DWORD   ?
sieve    BYTE    10000 DUP(1)
string   BYTE    40 DUP (?)
prompt1  BYTE    "Enter number of primes: ", 0
prompt2  BYTE    "prime number: ", 0
prompt3  BYTE    ", ", 0
primenum DWORD    11 DUP (?), 0
prime    BYTE     11 DUP (?), 0

.CODE

genPrimes   PROC
           ; push   ebp                  ; save base pointer
           ; mov    ebp, esp             ; establish stack frame
           ; push   ebx
            ; CODE
            call GenPrimes2 ;call function in genprimes.asm to push primes to stack

            sub esp, 4    ;move esp down
            sub esp, 4    ;esp points to first value

            mov ebx, 4 ; counter
            mov ecx, 0 ; index register to hold value of esp that will be put into primenum array


            loopArray:         ;this loop fills primenum with all primes put on the stack in genprimes.asm
                    mov ecx, [esp]
                    sub esp, 4
                    mov primenum[ebx], ecx
                    add ebx, 4
                    cmp ebx, 2200
            jb  loopArray

                mov ebx, 4
                mov eax, 0
                ;This loop is for debug purposes only, i want to see if the array primenum has the value 13, which is does
                ;because i can see it get copied into ecx. However, i get garbage in my output where 13 should be.
                PrintLoop2:             
                    mov ecx, primenum[ebx] ; Prime numbers are the non-zeros in this Array
                    add ebx, 4
                    cmp ebx, 400
                jb  PrintLoop2

                mov ebx, 4
                mov eax, 0

                add esp,2204  ;move esp back to return address
                ret                         ;exit genPrimes
genPrimes    ENDP
_sieve  PROC                            ; start of sieve program code
      input   prompt1, string, 40       ; read ASCII characters
      call  genPrimes
                atod string ; convert to integer the number of primes the user entered
                mov edx, 0

                ;this loop will print all the non-zero values stored in the array primenum, i have set all non-primes to 0's so that only
                ;they will be printed
                PrintLoop:
                mov ecx, primenum[ebx] ; Prime numbers are the non-zeros in this Array
                cmp primenum[ebx], 0
                jne printPrime
                
                add ebx, 4
                jmp  PrintLoop

                printPrime:
                dtoa prime, ecx ;convert the prime number to a string for printing
                output  prompt2, prime       ; output label and sum
                add ebx, 4
                inc edx
                cmp edx, eax
                jb  PrintLoop


      mov   eax, 0          ; exit with return code 0
      ret

_sieve  ENDP

END
.586
.MODEL FLAT


.STACK 4096                 
n=550
.data
    prime DWORD n DUP(?)

.code
GenPrimes2  PROC
mov ebx, 4
mov ecx, 0
loopArray:
    inc ecx
    mov prime[ebx], ecx
    add ebx, 4
    cmp ecx, n
jb  loopArray

mov eax, 3
mov ebx, 2
mov edx, 0

mov ecx,3

sieve_loop:

    cmp eax,ebx
    je skip

    mov edx, 0 ;zero out remainder
    div  ebx
    cmp edx,0 ; if remainder 0, not a prime
    je    NotPrime ;Jump if is a factor, since it cant be prime

; compare eax with n, if equal increment ebx
    cmp ecx,n
    jge    incrementEbx

;  compare ebx with n, if equal end sieve
    cmp ebx, n
    je sieve_end

    inc ecx
    mov eax, ecx

jmp sieve_loop

skip:
inc eax
jmp sieve_loop


NotPrime:
    mov eax, ecx ; store count in eax
    imul ecx, 4
    mov prime[ecx],0
    mov ecx, eax
    inc ecx ; increment ecx count
    inc eax ; increment eax divisor
    jmp sieve_loop

incrementEbx:
inc ebx
mov eax, 3 ; dividend
mov ecx, 3 ; counter

jmp sieve_loop


sieve_end:
    mov ebx, 4
    mov eax, 0
; *************  Add break point on print loop, ecx will be loading with primes and 0's  ********************
; *************  All non-prime numbers have been changed to a 0                          ********************


    PrintLoop:
    mov ecx, prime[ebx] ; Prime numbers are the non-zeros in this Array
    push   ecx
    add ebx, 4
    cmp ebx, 2200
    jb  PrintLoop

        add esp,2196
    mov   eax, 0          ; exit with return code 0
    ret
GenPrimes2 ENDP
END
.586
.MODEL FLAT
PUBLIC wtoaproc, atowproc, dtoaproc, atodproc

.CODE

; wtoaproc(source, dest)
; convert integer (source) to string of 6 characters at given destination address
; source integer passed as a doubleword, but only low-order word is processed
wtoaproc    PROC
            push   ebp                  ; save base pointer
            mov    ebp, esp             ; establish stack frame
            push   eax                  ; Save registers
            push   ebx
            push   ecx
            push   edx
            push   edi
            pushfd                     ; save flags

            mov    eax, [ebp+8]        ; first parameter (source integer)
            and    eax, 0ffffh         ; mask high-order word
            mov    edi, [ebp+12]       ; second parameter (dest offset)
ifSpecW:    cmp    ax,8000h            ; special case -32,768?
            jne    EndIfSpecW          ; if not, then normal case
            mov    BYTE PTR [edi],'-'  ; manually put in ASCII codes
            mov    BYTE PTR [edi+1],'3'  ;   for -32,768
            mov    BYTE PTR [edi+2],'2'
            mov    BYTE PTR [edi+3],'7'
            mov    BYTE PTR [edi+4],'6'
            mov    BYTE PTR [edi+5],'8'
            jmp    ExitIToA            ; done with special case
EndIfSpecW:

            push eax                   ; save source number

            mov    al,' '              ; put blanks in
            mov    ecx,5               ;   first five
            cld                        ;   bytes of
            rep stosb                  ;   destination field

            pop    eax                 ; restore source number
            mov    cl,' '              ; default sign (blank for +)
IfNegW:     cmp    ax,0                ; check sign of number
            jge    EndIfNegW           ; skip if not negative
            mov    cl,'-'              ; sign for negative number
            neg    ax                  ; number in AX now >= 0
EndIfNegW:

            mov    bx,10               ; divisor

WhileMoreW: mov    dx,0                ; extend number to doubleword
            div    bx                  ; divide by 10
            add    dl,'0'              ; convert remainder to character
            mov    [edi],dl            ; put character in string
            dec    edi                 ; move forward to next position
            cmp    ax,0                ; check quotient
            jnz    WhileMoreW          ; continue if quotient not zero

            mov    [edi],cl            ; insert blank or "-" for sign

ExitIToA:   popfd                      ; restore flags and registers
            pop    edi
            pop    edx
            pop    ecx
            pop    ebx
            pop    eax
            pop    ebp
            ret                        ;exit
wtoaproc    ENDP

; dtoaproc(source, dest)
; convert double (source) to string of 11 characters at given destination address
dtoaproc    PROC   NEAR32
            push   ebp                 ; save base pointer
            mov    ebp, esp            ; establish stack frame
            push   eax                 ; Save registers
            push   ebx                 ;   used by
            push   ecx                 ;   procedure
            push   edx
            push   edi
            pushfd                      ; save flags

            mov    eax, [ebp+8]         ; first parameter (source double)
            mov    edi, [ebp+12]        ; second parameter (dest addr)
ifSpecialD: cmp    eax,80000000h        ; special case -2,147,483,648?
            jne    EndIfSpecialD        ; if not, then normal case
            mov    BYTE PTR [edi],'-'   ; manually put in ASCII codes
            mov    BYTE PTR [edi+1],'2' ;   for -2,147,483,648
            mov    BYTE PTR [edi+2],'1'
            mov    BYTE PTR [edi+3],'4'
            mov    BYTE PTR [edi+4],'7'
            mov    BYTE PTR [edi+5],'4'
            mov    BYTE PTR [edi+6],'8'
            mov    BYTE PTR [edi+7],'3'
            mov    BYTE PTR [edi+8],'6'
            mov    BYTE PTR [edi+9],'4'
            mov    BYTE PTR [edi+10],'8'
            jmp    ExitDToA            ; done with special case
EndIfSpecialD:

            push   eax                 ; save source number

            mov    al,' '              ; put blanks in
            mov    ecx,10              ;   first ten
            cld                        ;   bytes of
            rep stosb                  ;   destination field

            pop    eax                 ; copy source number
            mov    cl,' '              ; default sign (blank for +)
IfNegD:     cmp    eax,0               ; check sign of number
            jge    EndIfNegD           ; skip if not negative
            mov    cl,'-'              ; sign for negative number
            neg    eax                 ; number in EAX now >= 0
EndIfNegD:

            mov    ebx,10              ; divisor

WhileMoreD: mov    edx,0               ; extend number to doubleword
            div    ebx                 ; divide by 10
            add    dl,30h              ; convert remainder to character
            mov    [edi],dl            ; put character in string
            dec    edi                 ; move forward to next position
            cmp    eax,0               ; check quotient
            jnz    WhileMoreD          ; continue if quotient not zero

            mov    [edi],cl            ; insert blank or "-" for sign

ExitDToA:   popfd                      ; restore flags and registers
            pop    edi
            pop    edx
            pop    ecx
            pop    ebx
            pop    eax
            pop    ebp
            ret                        ;exit
dtoaproc    ENDP

; atowproc(source)
; Procedure to scan data segment starting at source address, interpreting
; ASCII characters as an word-size integer value which is returned in AX.

; Leading blanks are skipped.  A leading - or + sign is acceptable.
; Digit(s) must immediately follow the sign (if any).
; Memory scan is terminated by any non-digit.

; No error checking is done. If the number is outside the range for a
; signed word, then the return value is undefined.

atowproc    PROC
            push   ebp                 ; save base pointer
            mov    ebp, esp            ; establish stack frame
            sub    esp, 2              ; local space for sign
            push   ebx                 ; Save registers
            push   edx
            push   esi
            pushfd                     ; save flags

            mov    esi,[ebp+8]         ; get parameter (source addr)

WhileBlankW:cmp    BYTE PTR [esi],' '  ; space?
            jne    EndWhileBlankW      ; exit if not
            inc    esi                 ; increment character pointer
            jmp    WhileBlankW         ; and try again
EndWhileBlankW:

            mov    ax,1                ; default sign multiplier
IfPlusW:    cmp    BYTE PTR [esi],'+'  ; leading + ?
            je     SkipSignW           ; if so, skip over
IfMinusW:   cmp    BYTE PTR [esi],'-'  ; leading - ?
            jne    EndIfSignW          ; if not, save default +
            mov    ax,-1               ; -1 for minus sign
SkipSignW:  inc    esi                 ; move past sign
EndIfSignW:

            mov    [ebp-2],ax          ; save sign multiplier
            mov    ax,0                ; number being accumulated

WhileDigitW:cmp    BYTE PTR [esi],'0'  ; next character >= '0'
            jnge   EndWhileDigitW      ; exit if not
            cmp    BYTE PTR [esi],'9'  ; next character <= '9'
            jnle   EndWhileDigitW      ; not a digit if bigger than '9'
            imul   ax,10               ; multiply old number by 10
            mov    bl,[esi]            ; ASCII character to BL
            and    bx,000Fh            ; convert to single-digit integer
            add    ax,bx               ; add to sum
            inc    esi                 ; increment character pointer
            jmp    WhileDigitW         ; go try next character
EndWhileDigitW:

; if value is < 8000h, multiply by sign
            cmp    ax,8000h            ; 8000h?
            jnb    endIfMaxW           ; skip if not
            imul   WORD PTR [ebp-2]    ; make signed number
endIfMaxW:

            popfd                      ; restore flags
            pop    esi                 ; restore registers
            pop    edx
            pop    ebx
            mov    esp, ebp            ; delete local variable space
            pop    ebp
            ret                        ; exit
atowproc    ENDP

; atodproc(source)
; Procedure to scan data segment starting at source address, interpreting
; ASCII characters as an doubleword-size integer value which is returned in EAX.

; Leading blanks are skipped.  A leading - or + sign is acceptable.
; Digit(s) must immediately follow the sign (if any).
; Memory scan is terminated by any non-digit.

; No error checking is done. If the number is outside the range for a
; signed word, then the return value is undefined.

atodproc    PROC
            push   ebp                 ; save base pointer
            mov    ebp, esp            ; establish stack frame
            sub    esp, 4              ; local space for sign
            push   ebx                 ; Save registers
            push   edx
            push   esi
            pushfd                     ; save flags

            mov    esi,[ebp+8]         ; get parameter (source addr)

WhileBlankD:cmp    BYTE PTR [esi],' '  ; space?
            jne    EndWhileBlankD      ; exit if not
            inc    esi                 ; increment character pointer
            jmp    WhileBlankD         ; and try again
EndWhileBlankD:

            mov    eax,1               ; default sign multiplier
IfPlusD:    cmp    BYTE PTR [esi],'+'  ; leading + ?
            je     SkipSignD           ; if so, skip over
IfMinusD:   cmp    BYTE PTR [esi],'-'  ; leading - ?
            jne    EndIfSignD          ; if not, save default +
            mov    eax,-1              ; -1 for minus sign
SkipSignD:  inc    esi                 ; move past sign
EndIfSignD:

            mov    [ebp-4],eax         ; save sign multiplier
            mov    eax,0               ; number being accumulated

WhileDigitD:cmp    BYTE PTR [esi],'0'  ; compare next character to '0'
            jl     EndWhileDigitD      ; not a digit if smaller than '0'
            cmp    BYTE PTR [esi],'9'  ; compare to '9'
            jg     EndWhileDigitD      ; not a digit if bigger than '9'
            imul   eax,10              ; multiply old number by 10
            mov    bl,[esi]            ; ASCII character to BL
            and    ebx,0000000Fh       ; convert to single-digit integer
            add    eax,ebx             ; add to sum
            inc    esi                 ; increment character pointer
            jmp    WhileDigitD         ; go try next character
EndWhileDigitD:

; if value is < 80000000h, multiply by sign
            cmp    eax,80000000h       ; 80000000h?
            jnb    endIfMaxD           ; skip if not
            imul   DWORD PTR [ebp-4]   ; make signed number
endIfMaxD:

            popfd                      ; restore flags
            pop    esi                 ; restore registers
            pop    edx
            pop    ebx
            mov    esp, ebp            ; delete local variable space
            pop    ebp
            ret                        ; exit
atodproc    ENDP

            END
genprimes.asm:

.586
.MODEL FLAT
INCLUDE io.h
EXTERN GenPrimes2:PROC
PUBLIC genPrimes
.STACK 4096                 ; reserve 4096-byte stack
.DATA                       ; reserve storage for data

count    DWORD   ?
sieve    BYTE    10000 DUP(1)
string   BYTE    40 DUP (?)
prompt1  BYTE    "Enter number of primes: ", 0
prompt2  BYTE    "prime number: ", 0
prompt3  BYTE    ", ", 0
primenum DWORD    11 DUP (?), 0
prime    BYTE     11 DUP (?), 0

.CODE

genPrimes   PROC
           ; push   ebp                  ; save base pointer
           ; mov    ebp, esp             ; establish stack frame
           ; push   ebx
            ; CODE
            call GenPrimes2 ;call function in genprimes.asm to push primes to stack

            sub esp, 4    ;move esp down
            sub esp, 4    ;esp points to first value

            mov ebx, 4 ; counter
            mov ecx, 0 ; index register to hold value of esp that will be put into primenum array


            loopArray:         ;this loop fills primenum with all primes put on the stack in genprimes.asm
                    mov ecx, [esp]
                    sub esp, 4
                    mov primenum[ebx], ecx
                    add ebx, 4
                    cmp ebx, 2200
            jb  loopArray

                mov ebx, 4
                mov eax, 0
                ;This loop is for debug purposes only, i want to see if the array primenum has the value 13, which is does
                ;because i can see it get copied into ecx. However, i get garbage in my output where 13 should be.
                PrintLoop2:             
                    mov ecx, primenum[ebx] ; Prime numbers are the non-zeros in this Array
                    add ebx, 4
                    cmp ebx, 400
                jb  PrintLoop2

                mov ebx, 4
                mov eax, 0

                add esp,2204  ;move esp back to return address
                ret                         ;exit genPrimes
genPrimes    ENDP
_sieve  PROC                            ; start of sieve program code
      input   prompt1, string, 40       ; read ASCII characters
      call  genPrimes
                atod string ; convert to integer the number of primes the user entered
                mov edx, 0

                ;this loop will print all the non-zero values stored in the array primenum, i have set all non-primes to 0's so that only
                ;they will be printed
                PrintLoop:
                mov ecx, primenum[ebx] ; Prime numbers are the non-zeros in this Array
                cmp primenum[ebx], 0
                jne printPrime
                
                add ebx, 4
                jmp  PrintLoop

                printPrime:
                dtoa prime, ecx ;convert the prime number to a string for printing
                output  prompt2, prime       ; output label and sum
                add ebx, 4
                inc edx
                cmp edx, eax
                jb  PrintLoop


      mov   eax, 0          ; exit with return code 0
      ret

_sieve  ENDP

END
.586
.MODEL FLAT


.STACK 4096                 
n=550
.data
    prime DWORD n DUP(?)

.code
GenPrimes2  PROC
mov ebx, 4
mov ecx, 0
loopArray:
    inc ecx
    mov prime[ebx], ecx
    add ebx, 4
    cmp ecx, n
jb  loopArray

mov eax, 3
mov ebx, 2
mov edx, 0

mov ecx,3

sieve_loop:

    cmp eax,ebx
    je skip

    mov edx, 0 ;zero out remainder
    div  ebx
    cmp edx,0 ; if remainder 0, not a prime
    je    NotPrime ;Jump if is a factor, since it cant be prime

; compare eax with n, if equal increment ebx
    cmp ecx,n
    jge    incrementEbx

;  compare ebx with n, if equal end sieve
    cmp ebx, n
    je sieve_end

    inc ecx
    mov eax, ecx

jmp sieve_loop

skip:
inc eax
jmp sieve_loop


NotPrime:
    mov eax, ecx ; store count in eax
    imul ecx, 4
    mov prime[ecx],0
    mov ecx, eax
    inc ecx ; increment ecx count
    inc eax ; increment eax divisor
    jmp sieve_loop

incrementEbx:
inc ebx
mov eax, 3 ; dividend
mov ecx, 3 ; counter

jmp sieve_loop


sieve_end:
    mov ebx, 4
    mov eax, 0
; *************  Add break point on print loop, ecx will be loading with primes and 0's  ********************
; *************  All non-prime numbers have been changed to a 0                          ********************


    PrintLoop:
    mov ecx, prime[ebx] ; Prime numbers are the non-zeros in this Array
    push   ecx
    add ebx, 4
    cmp ebx, 2200
    jb  PrintLoop

        add esp,2196
    mov   eax, 0          ; exit with return code 0
    ret
GenPrimes2 ENDP
END
.586
.MODEL FLAT
PUBLIC wtoaproc, atowproc, dtoaproc, atodproc

.CODE

; wtoaproc(source, dest)
; convert integer (source) to string of 6 characters at given destination address
; source integer passed as a doubleword, but only low-order word is processed
wtoaproc    PROC
            push   ebp                  ; save base pointer
            mov    ebp, esp             ; establish stack frame
            push   eax                  ; Save registers
            push   ebx
            push   ecx
            push   edx
            push   edi
            pushfd                     ; save flags

            mov    eax, [ebp+8]        ; first parameter (source integer)
            and    eax, 0ffffh         ; mask high-order word
            mov    edi, [ebp+12]       ; second parameter (dest offset)
ifSpecW:    cmp    ax,8000h            ; special case -32,768?
            jne    EndIfSpecW          ; if not, then normal case
            mov    BYTE PTR [edi],'-'  ; manually put in ASCII codes
            mov    BYTE PTR [edi+1],'3'  ;   for -32,768
            mov    BYTE PTR [edi+2],'2'
            mov    BYTE PTR [edi+3],'7'
            mov    BYTE PTR [edi+4],'6'
            mov    BYTE PTR [edi+5],'8'
            jmp    ExitIToA            ; done with special case
EndIfSpecW:

            push eax                   ; save source number

            mov    al,' '              ; put blanks in
            mov    ecx,5               ;   first five
            cld                        ;   bytes of
            rep stosb                  ;   destination field

            pop    eax                 ; restore source number
            mov    cl,' '              ; default sign (blank for +)
IfNegW:     cmp    ax,0                ; check sign of number
            jge    EndIfNegW           ; skip if not negative
            mov    cl,'-'              ; sign for negative number
            neg    ax                  ; number in AX now >= 0
EndIfNegW:

            mov    bx,10               ; divisor

WhileMoreW: mov    dx,0                ; extend number to doubleword
            div    bx                  ; divide by 10
            add    dl,'0'              ; convert remainder to character
            mov    [edi],dl            ; put character in string
            dec    edi                 ; move forward to next position
            cmp    ax,0                ; check quotient
            jnz    WhileMoreW          ; continue if quotient not zero

            mov    [edi],cl            ; insert blank or "-" for sign

ExitIToA:   popfd                      ; restore flags and registers
            pop    edi
            pop    edx
            pop    ecx
            pop    ebx
            pop    eax
            pop    ebp
            ret                        ;exit
wtoaproc    ENDP

; dtoaproc(source, dest)
; convert double (source) to string of 11 characters at given destination address
dtoaproc    PROC   NEAR32
            push   ebp                 ; save base pointer
            mov    ebp, esp            ; establish stack frame
            push   eax                 ; Save registers
            push   ebx                 ;   used by
            push   ecx                 ;   procedure
            push   edx
            push   edi
            pushfd                      ; save flags

            mov    eax, [ebp+8]         ; first parameter (source double)
            mov    edi, [ebp+12]        ; second parameter (dest addr)
ifSpecialD: cmp    eax,80000000h        ; special case -2,147,483,648?
            jne    EndIfSpecialD        ; if not, then normal case
            mov    BYTE PTR [edi],'-'   ; manually put in ASCII codes
            mov    BYTE PTR [edi+1],'2' ;   for -2,147,483,648
            mov    BYTE PTR [edi+2],'1'
            mov    BYTE PTR [edi+3],'4'
            mov    BYTE PTR [edi+4],'7'
            mov    BYTE PTR [edi+5],'4'
            mov    BYTE PTR [edi+6],'8'
            mov    BYTE PTR [edi+7],'3'
            mov    BYTE PTR [edi+8],'6'
            mov    BYTE PTR [edi+9],'4'
            mov    BYTE PTR [edi+10],'8'
            jmp    ExitDToA            ; done with special case
EndIfSpecialD:

            push   eax                 ; save source number

            mov    al,' '              ; put blanks in
            mov    ecx,10              ;   first ten
            cld                        ;   bytes of
            rep stosb                  ;   destination field

            pop    eax                 ; copy source number
            mov    cl,' '              ; default sign (blank for +)
IfNegD:     cmp    eax,0               ; check sign of number
            jge    EndIfNegD           ; skip if not negative
            mov    cl,'-'              ; sign for negative number
            neg    eax                 ; number in EAX now >= 0
EndIfNegD:

            mov    ebx,10              ; divisor

WhileMoreD: mov    edx,0               ; extend number to doubleword
            div    ebx                 ; divide by 10
            add    dl,30h              ; convert remainder to character
            mov    [edi],dl            ; put character in string
            dec    edi                 ; move forward to next position
            cmp    eax,0               ; check quotient
            jnz    WhileMoreD          ; continue if quotient not zero

            mov    [edi],cl            ; insert blank or "-" for sign

ExitDToA:   popfd                      ; restore flags and registers
            pop    edi
            pop    edx
            pop    ecx
            pop    ebx
            pop    eax
            pop    ebp
            ret                        ;exit
dtoaproc    ENDP

; atowproc(source)
; Procedure to scan data segment starting at source address, interpreting
; ASCII characters as an word-size integer value which is returned in AX.

; Leading blanks are skipped.  A leading - or + sign is acceptable.
; Digit(s) must immediately follow the sign (if any).
; Memory scan is terminated by any non-digit.

; No error checking is done. If the number is outside the range for a
; signed word, then the return value is undefined.

atowproc    PROC
            push   ebp                 ; save base pointer
            mov    ebp, esp            ; establish stack frame
            sub    esp, 2              ; local space for sign
            push   ebx                 ; Save registers
            push   edx
            push   esi
            pushfd                     ; save flags

            mov    esi,[ebp+8]         ; get parameter (source addr)

WhileBlankW:cmp    BYTE PTR [esi],' '  ; space?
            jne    EndWhileBlankW      ; exit if not
            inc    esi                 ; increment character pointer
            jmp    WhileBlankW         ; and try again
EndWhileBlankW:

            mov    ax,1                ; default sign multiplier
IfPlusW:    cmp    BYTE PTR [esi],'+'  ; leading + ?
            je     SkipSignW           ; if so, skip over
IfMinusW:   cmp    BYTE PTR [esi],'-'  ; leading - ?
            jne    EndIfSignW          ; if not, save default +
            mov    ax,-1               ; -1 for minus sign
SkipSignW:  inc    esi                 ; move past sign
EndIfSignW:

            mov    [ebp-2],ax          ; save sign multiplier
            mov    ax,0                ; number being accumulated

WhileDigitW:cmp    BYTE PTR [esi],'0'  ; next character >= '0'
            jnge   EndWhileDigitW      ; exit if not
            cmp    BYTE PTR [esi],'9'  ; next character <= '9'
            jnle   EndWhileDigitW      ; not a digit if bigger than '9'
            imul   ax,10               ; multiply old number by 10
            mov    bl,[esi]            ; ASCII character to BL
            and    bx,000Fh            ; convert to single-digit integer
            add    ax,bx               ; add to sum
            inc    esi                 ; increment character pointer
            jmp    WhileDigitW         ; go try next character
EndWhileDigitW:

; if value is < 8000h, multiply by sign
            cmp    ax,8000h            ; 8000h?
            jnb    endIfMaxW           ; skip if not
            imul   WORD PTR [ebp-2]    ; make signed number
endIfMaxW:

            popfd                      ; restore flags
            pop    esi                 ; restore registers
            pop    edx
            pop    ebx
            mov    esp, ebp            ; delete local variable space
            pop    ebp
            ret                        ; exit
atowproc    ENDP

; atodproc(source)
; Procedure to scan data segment starting at source address, interpreting
; ASCII characters as an doubleword-size integer value which is returned in EAX.

; Leading blanks are skipped.  A leading - or + sign is acceptable.
; Digit(s) must immediately follow the sign (if any).
; Memory scan is terminated by any non-digit.

; No error checking is done. If the number is outside the range for a
; signed word, then the return value is undefined.

atodproc    PROC
            push   ebp                 ; save base pointer
            mov    ebp, esp            ; establish stack frame
            sub    esp, 4              ; local space for sign
            push   ebx                 ; Save registers
            push   edx
            push   esi
            pushfd                     ; save flags

            mov    esi,[ebp+8]         ; get parameter (source addr)

WhileBlankD:cmp    BYTE PTR [esi],' '  ; space?
            jne    EndWhileBlankD      ; exit if not
            inc    esi                 ; increment character pointer
            jmp    WhileBlankD         ; and try again
EndWhileBlankD:

            mov    eax,1               ; default sign multiplier
IfPlusD:    cmp    BYTE PTR [esi],'+'  ; leading + ?
            je     SkipSignD           ; if so, skip over
IfMinusD:   cmp    BYTE PTR [esi],'-'  ; leading - ?
            jne    EndIfSignD          ; if not, save default +
            mov    eax,-1              ; -1 for minus sign
SkipSignD:  inc    esi                 ; move past sign
EndIfSignD:

            mov    [ebp-4],eax         ; save sign multiplier
            mov    eax,0               ; number being accumulated

WhileDigitD:cmp    BYTE PTR [esi],'0'  ; compare next character to '0'
            jl     EndWhileDigitD      ; not a digit if smaller than '0'
            cmp    BYTE PTR [esi],'9'  ; compare to '9'
            jg     EndWhileDigitD      ; not a digit if bigger than '9'
            imul   eax,10              ; multiply old number by 10
            mov    bl,[esi]            ; ASCII character to BL
            and    ebx,0000000Fh       ; convert to single-digit integer
            add    eax,ebx             ; add to sum
            inc    esi                 ; increment character pointer
            jmp    WhileDigitD         ; go try next character
EndWhileDigitD:

; if value is < 80000000h, multiply by sign
            cmp    eax,80000000h       ; 80000000h?
            jnb    endIfMaxD           ; skip if not
            imul   DWORD PTR [ebp-4]   ; make signed number
endIfMaxD:

            popfd                      ; restore flags
            pop    esi                 ; restore registers
            pop    edx
            pop    ebx
            mov    esp, ebp            ; delete local variable space
            pop    ebp
            ret                        ; exit
atodproc    ENDP

            END
io.asm:

.586
.MODEL FLAT
INCLUDE io.h
EXTERN GenPrimes2:PROC
PUBLIC genPrimes
.STACK 4096                 ; reserve 4096-byte stack
.DATA                       ; reserve storage for data

count    DWORD   ?
sieve    BYTE    10000 DUP(1)
string   BYTE    40 DUP (?)
prompt1  BYTE    "Enter number of primes: ", 0
prompt2  BYTE    "prime number: ", 0
prompt3  BYTE    ", ", 0
primenum DWORD    11 DUP (?), 0
prime    BYTE     11 DUP (?), 0

.CODE

genPrimes   PROC
           ; push   ebp                  ; save base pointer
           ; mov    ebp, esp             ; establish stack frame
           ; push   ebx
            ; CODE
            call GenPrimes2 ;call function in genprimes.asm to push primes to stack

            sub esp, 4    ;move esp down
            sub esp, 4    ;esp points to first value

            mov ebx, 4 ; counter
            mov ecx, 0 ; index register to hold value of esp that will be put into primenum array


            loopArray:         ;this loop fills primenum with all primes put on the stack in genprimes.asm
                    mov ecx, [esp]
                    sub esp, 4
                    mov primenum[ebx], ecx
                    add ebx, 4
                    cmp ebx, 2200
            jb  loopArray

                mov ebx, 4
                mov eax, 0
                ;This loop is for debug purposes only, i want to see if the array primenum has the value 13, which is does
                ;because i can see it get copied into ecx. However, i get garbage in my output where 13 should be.
                PrintLoop2:             
                    mov ecx, primenum[ebx] ; Prime numbers are the non-zeros in this Array
                    add ebx, 4
                    cmp ebx, 400
                jb  PrintLoop2

                mov ebx, 4
                mov eax, 0

                add esp,2204  ;move esp back to return address
                ret                         ;exit genPrimes
genPrimes    ENDP
_sieve  PROC                            ; start of sieve program code
      input   prompt1, string, 40       ; read ASCII characters
      call  genPrimes
                atod string ; convert to integer the number of primes the user entered
                mov edx, 0

                ;this loop will print all the non-zero values stored in the array primenum, i have set all non-primes to 0's so that only
                ;they will be printed
                PrintLoop:
                mov ecx, primenum[ebx] ; Prime numbers are the non-zeros in this Array
                cmp primenum[ebx], 0
                jne printPrime
                
                add ebx, 4
                jmp  PrintLoop

                printPrime:
                dtoa prime, ecx ;convert the prime number to a string for printing
                output  prompt2, prime       ; output label and sum
                add ebx, 4
                inc edx
                cmp edx, eax
                jb  PrintLoop


      mov   eax, 0          ; exit with return code 0
      ret

_sieve  ENDP

END
.586
.MODEL FLAT


.STACK 4096                 
n=550
.data
    prime DWORD n DUP(?)

.code
GenPrimes2  PROC
mov ebx, 4
mov ecx, 0
loopArray:
    inc ecx
    mov prime[ebx], ecx
    add ebx, 4
    cmp ecx, n
jb  loopArray

mov eax, 3
mov ebx, 2
mov edx, 0

mov ecx,3

sieve_loop:

    cmp eax,ebx
    je skip

    mov edx, 0 ;zero out remainder
    div  ebx
    cmp edx,0 ; if remainder 0, not a prime
    je    NotPrime ;Jump if is a factor, since it cant be prime

; compare eax with n, if equal increment ebx
    cmp ecx,n
    jge    incrementEbx

;  compare ebx with n, if equal end sieve
    cmp ebx, n
    je sieve_end

    inc ecx
    mov eax, ecx

jmp sieve_loop

skip:
inc eax
jmp sieve_loop


NotPrime:
    mov eax, ecx ; store count in eax
    imul ecx, 4
    mov prime[ecx],0
    mov ecx, eax
    inc ecx ; increment ecx count
    inc eax ; increment eax divisor
    jmp sieve_loop

incrementEbx:
inc ebx
mov eax, 3 ; dividend
mov ecx, 3 ; counter

jmp sieve_loop


sieve_end:
    mov ebx, 4
    mov eax, 0
; *************  Add break point on print loop, ecx will be loading with primes and 0's  ********************
; *************  All non-prime numbers have been changed to a 0                          ********************


    PrintLoop:
    mov ecx, prime[ebx] ; Prime numbers are the non-zeros in this Array
    push   ecx
    add ebx, 4
    cmp ebx, 2200
    jb  PrintLoop

        add esp,2196
    mov   eax, 0          ; exit with return code 0
    ret
GenPrimes2 ENDP
END
.586
.MODEL FLAT
PUBLIC wtoaproc, atowproc, dtoaproc, atodproc

.CODE

; wtoaproc(source, dest)
; convert integer (source) to string of 6 characters at given destination address
; source integer passed as a doubleword, but only low-order word is processed
wtoaproc    PROC
            push   ebp                  ; save base pointer
            mov    ebp, esp             ; establish stack frame
            push   eax                  ; Save registers
            push   ebx
            push   ecx
            push   edx
            push   edi
            pushfd                     ; save flags

            mov    eax, [ebp+8]        ; first parameter (source integer)
            and    eax, 0ffffh         ; mask high-order word
            mov    edi, [ebp+12]       ; second parameter (dest offset)
ifSpecW:    cmp    ax,8000h            ; special case -32,768?
            jne    EndIfSpecW          ; if not, then normal case
            mov    BYTE PTR [edi],'-'  ; manually put in ASCII codes
            mov    BYTE PTR [edi+1],'3'  ;   for -32,768
            mov    BYTE PTR [edi+2],'2'
            mov    BYTE PTR [edi+3],'7'
            mov    BYTE PTR [edi+4],'6'
            mov    BYTE PTR [edi+5],'8'
            jmp    ExitIToA            ; done with special case
EndIfSpecW:

            push eax                   ; save source number

            mov    al,' '              ; put blanks in
            mov    ecx,5               ;   first five
            cld                        ;   bytes of
            rep stosb                  ;   destination field

            pop    eax                 ; restore source number
            mov    cl,' '              ; default sign (blank for +)
IfNegW:     cmp    ax,0                ; check sign of number
            jge    EndIfNegW           ; skip if not negative
            mov    cl,'-'              ; sign for negative number
            neg    ax                  ; number in AX now >= 0
EndIfNegW:

            mov    bx,10               ; divisor

WhileMoreW: mov    dx,0                ; extend number to doubleword
            div    bx                  ; divide by 10
            add    dl,'0'              ; convert remainder to character
            mov    [edi],dl            ; put character in string
            dec    edi                 ; move forward to next position
            cmp    ax,0                ; check quotient
            jnz    WhileMoreW          ; continue if quotient not zero

            mov    [edi],cl            ; insert blank or "-" for sign

ExitIToA:   popfd                      ; restore flags and registers
            pop    edi
            pop    edx
            pop    ecx
            pop    ebx
            pop    eax
            pop    ebp
            ret                        ;exit
wtoaproc    ENDP

; dtoaproc(source, dest)
; convert double (source) to string of 11 characters at given destination address
dtoaproc    PROC   NEAR32
            push   ebp                 ; save base pointer
            mov    ebp, esp            ; establish stack frame
            push   eax                 ; Save registers
            push   ebx                 ;   used by
            push   ecx                 ;   procedure
            push   edx
            push   edi
            pushfd                      ; save flags

            mov    eax, [ebp+8]         ; first parameter (source double)
            mov    edi, [ebp+12]        ; second parameter (dest addr)
ifSpecialD: cmp    eax,80000000h        ; special case -2,147,483,648?
            jne    EndIfSpecialD        ; if not, then normal case
            mov    BYTE PTR [edi],'-'   ; manually put in ASCII codes
            mov    BYTE PTR [edi+1],'2' ;   for -2,147,483,648
            mov    BYTE PTR [edi+2],'1'
            mov    BYTE PTR [edi+3],'4'
            mov    BYTE PTR [edi+4],'7'
            mov    BYTE PTR [edi+5],'4'
            mov    BYTE PTR [edi+6],'8'
            mov    BYTE PTR [edi+7],'3'
            mov    BYTE PTR [edi+8],'6'
            mov    BYTE PTR [edi+9],'4'
            mov    BYTE PTR [edi+10],'8'
            jmp    ExitDToA            ; done with special case
EndIfSpecialD:

            push   eax                 ; save source number

            mov    al,' '              ; put blanks in
            mov    ecx,10              ;   first ten
            cld                        ;   bytes of
            rep stosb                  ;   destination field

            pop    eax                 ; copy source number
            mov    cl,' '              ; default sign (blank for +)
IfNegD:     cmp    eax,0               ; check sign of number
            jge    EndIfNegD           ; skip if not negative
            mov    cl,'-'              ; sign for negative number
            neg    eax                 ; number in EAX now >= 0
EndIfNegD:

            mov    ebx,10              ; divisor

WhileMoreD: mov    edx,0               ; extend number to doubleword
            div    ebx                 ; divide by 10
            add    dl,30h              ; convert remainder to character
            mov    [edi],dl            ; put character in string
            dec    edi                 ; move forward to next position
            cmp    eax,0               ; check quotient
            jnz    WhileMoreD          ; continue if quotient not zero

            mov    [edi],cl            ; insert blank or "-" for sign

ExitDToA:   popfd                      ; restore flags and registers
            pop    edi
            pop    edx
            pop    ecx
            pop    ebx
            pop    eax
            pop    ebp
            ret                        ;exit
dtoaproc    ENDP

; atowproc(source)
; Procedure to scan data segment starting at source address, interpreting
; ASCII characters as an word-size integer value which is returned in AX.

; Leading blanks are skipped.  A leading - or + sign is acceptable.
; Digit(s) must immediately follow the sign (if any).
; Memory scan is terminated by any non-digit.

; No error checking is done. If the number is outside the range for a
; signed word, then the return value is undefined.

atowproc    PROC
            push   ebp                 ; save base pointer
            mov    ebp, esp            ; establish stack frame
            sub    esp, 2              ; local space for sign
            push   ebx                 ; Save registers
            push   edx
            push   esi
            pushfd                     ; save flags

            mov    esi,[ebp+8]         ; get parameter (source addr)

WhileBlankW:cmp    BYTE PTR [esi],' '  ; space?
            jne    EndWhileBlankW      ; exit if not
            inc    esi                 ; increment character pointer
            jmp    WhileBlankW         ; and try again
EndWhileBlankW:

            mov    ax,1                ; default sign multiplier
IfPlusW:    cmp    BYTE PTR [esi],'+'  ; leading + ?
            je     SkipSignW           ; if so, skip over
IfMinusW:   cmp    BYTE PTR [esi],'-'  ; leading - ?
            jne    EndIfSignW          ; if not, save default +
            mov    ax,-1               ; -1 for minus sign
SkipSignW:  inc    esi                 ; move past sign
EndIfSignW:

            mov    [ebp-2],ax          ; save sign multiplier
            mov    ax,0                ; number being accumulated

WhileDigitW:cmp    BYTE PTR [esi],'0'  ; next character >= '0'
            jnge   EndWhileDigitW      ; exit if not
            cmp    BYTE PTR [esi],'9'  ; next character <= '9'
            jnle   EndWhileDigitW      ; not a digit if bigger than '9'
            imul   ax,10               ; multiply old number by 10
            mov    bl,[esi]            ; ASCII character to BL
            and    bx,000Fh            ; convert to single-digit integer
            add    ax,bx               ; add to sum
            inc    esi                 ; increment character pointer
            jmp    WhileDigitW         ; go try next character
EndWhileDigitW:

; if value is < 8000h, multiply by sign
            cmp    ax,8000h            ; 8000h?
            jnb    endIfMaxW           ; skip if not
            imul   WORD PTR [ebp-2]    ; make signed number
endIfMaxW:

            popfd                      ; restore flags
            pop    esi                 ; restore registers
            pop    edx
            pop    ebx
            mov    esp, ebp            ; delete local variable space
            pop    ebp
            ret                        ; exit
atowproc    ENDP

; atodproc(source)
; Procedure to scan data segment starting at source address, interpreting
; ASCII characters as an doubleword-size integer value which is returned in EAX.

; Leading blanks are skipped.  A leading - or + sign is acceptable.
; Digit(s) must immediately follow the sign (if any).
; Memory scan is terminated by any non-digit.

; No error checking is done. If the number is outside the range for a
; signed word, then the return value is undefined.

atodproc    PROC
            push   ebp                 ; save base pointer
            mov    ebp, esp            ; establish stack frame
            sub    esp, 4              ; local space for sign
            push   ebx                 ; Save registers
            push   edx
            push   esi
            pushfd                     ; save flags

            mov    esi,[ebp+8]         ; get parameter (source addr)

WhileBlankD:cmp    BYTE PTR [esi],' '  ; space?
            jne    EndWhileBlankD      ; exit if not
            inc    esi                 ; increment character pointer
            jmp    WhileBlankD         ; and try again
EndWhileBlankD:

            mov    eax,1               ; default sign multiplier
IfPlusD:    cmp    BYTE PTR [esi],'+'  ; leading + ?
            je     SkipSignD           ; if so, skip over
IfMinusD:   cmp    BYTE PTR [esi],'-'  ; leading - ?
            jne    EndIfSignD          ; if not, save default +
            mov    eax,-1              ; -1 for minus sign
SkipSignD:  inc    esi                 ; move past sign
EndIfSignD:

            mov    [ebp-4],eax         ; save sign multiplier
            mov    eax,0               ; number being accumulated

WhileDigitD:cmp    BYTE PTR [esi],'0'  ; compare next character to '0'
            jl     EndWhileDigitD      ; not a digit if smaller than '0'
            cmp    BYTE PTR [esi],'9'  ; compare to '9'
            jg     EndWhileDigitD      ; not a digit if bigger than '9'
            imul   eax,10              ; multiply old number by 10
            mov    bl,[esi]            ; ASCII character to BL
            and    ebx,0000000Fh       ; convert to single-digit integer
            add    eax,ebx             ; add to sum
            inc    esi                 ; increment character pointer
            jmp    WhileDigitD         ; go try next character
EndWhileDigitD:

; if value is < 80000000h, multiply by sign
            cmp    eax,80000000h       ; 80000000h?
            jnb    endIfMaxD           ; skip if not
            imul   DWORD PTR [ebp-4]   ; make signed number
endIfMaxD:

            popfd                      ; restore flags
            pop    esi                 ; restore registers
            pop    edx
            pop    ebx
            mov    esp, ebp            ; delete local variable space
            pop    ebp
            ret                        ; exit
atodproc    ENDP

            END
.586
.样板房
公共wtoaproc、atowproc、dtoaproc、atodproc
.代码
; wtoaproc(源、目标)
; 在给定的目标地址将整数(源)转换为6个字符的字符串
; 源整数作为双字传递,但只处理低阶字
wtoaproc程序
推动ebp;保存基指针
mov-ebp,esp;建立堆栈框架
推动eax;保存寄存器
推ebx
推ecx
推式edx
推式电子数据交换
pushfd;保存标志
mov-eax,[ebp+8];第一个参数(源整数)
和eax,0ffffh;屏蔽高阶字
移动电子数据交换[ebp+12];第二个参数(目标偏移量)
如果规格:cmp ax,8000h;特殊情况-32768?
jne-EndIfSpecW;如果不是,则为正常情况
mov字节PTR[edi],“-”;手动输入ASCII码
mov字节PTR[edi+1],'3';适用于-32768
mov字节PTR[edi+2],'2'
mov字节PTR[edi+3],'7'
mov字节PTR[edi+4],'6'
mov字节PTR[edi+5],'8'
jmp-ExitIToA;特殊情况下完成
EndIfSpecW:
推动eax;保存源代码
mov al,”;填空
mov-ecx,5;前五名
cld;字节
代表stosb;目的地字段
pop-eax;还原源代码
mov-cl';默认符号(对于+为空)
IfNegW:cmp-ax,0;核对号码
jge-EndIfNegW;如果不是负数,则跳过
mov-cl'-';负数符号
neg-ax;AX中的数字现在>=0
EndIfNegW:
mov-bx,10;除数
WhileMoreW:mov-dx,0;将数字扩展为双字
分区bx;除以10
加上dl,'0';将余数转换为字符
mov[edi],dl;将字符放入字符串中
dec-edi;前进到下一个位置
cmp-ax,0;校验商
jnz WhileMoreW;如果商不为零,则继续
mov[edi],cl;插入空白或“-”作为符号
存在:popfd;还原标志和寄存器
流行电子数据交换
波普edx
波普ecx
流行电子束
波普eax
流行ebp
ret;出口
wtoaproc ENDP
; dtoaproc(源、目标)
; 在给定的目标地址将双精度(源)转换为11个字符的字符串
dtoaproc PROC NEAR32
推动ebp;保存基指针
mov-ebp,esp;建立堆栈框架
推动eax;保存寄存器
推ebx;被使用
推动ecx;程序
推式edx
推式电子数据交换
pushfd;保存标志
mov-eax,[ebp+8];第一个参数(源双精度)
移动电子数据交换[ebp+12];第二个参数(dest addr)
如果特别许可:cmp eax,80000000h;特殊情况-2147483648?
jne-EndIfSpecialD;如果不是,则为正常情况
mov字节PTR[edi],“-”;手动输入ASCII码
mov字节PTR[edi+1],'2';适用于-2147483648
mov字节PTR[edi+2],'1'
mov字节PTR[edi+3],'4'
mov字节PTR[edi+4],'7'
mov字节PTR[edi+5],'4'
mov字节PTR[edi+6],'8'
mov字节PTR[edi+7],'3'
mov字节PTR[edi+8],'6'
mov字节PTR[edi+9],'4'
mov字节PTR[edi+10],'8'
jmp-ExitDToA;特殊情况下完成
EndIfSpecialD:
推动eax;保存源代码
mov al,”;填空
mov-ecx,10;前十名
cld;字节
代表stosb;目的地字段
pop-eax;复制源编号
mov-cl';默认符号(对于+为空)
IfNegD:cmp-eax,0;核对号码
jge-EndIfNegD;如果不是负数,则跳过
mov-cl'-';负数符号
neg-eax;EAX中的数字现在>=0
EndIfNegD:
mov  ecx, primenum[ebx] ; Prime numbers are the non-zeros in this Array
test ecx, ecx
jnz  printPrime