I am trying to write a program that figures out prime numers. It creates an array to 100. Edi should be the number. If the value at that location is 0, it's prime. It starts at 2 and goes to every second number making it not prime (sets it to 1). Then, it searches for the next prime, which is 3 and goes to every 3rd one setting it equal to 1. It doesn't like the two cmp statements. If I uncomment them, I get "This program has performed an illegal operation". I don't really understand why.



.386
.MODEL FLAT

ExitProcess PROTO NEAR32 stdcall, dwExitCode:DWORD

INCLUDE io.h

cr EQU 0dh
Lf EQU 0ah

.STACK 4096

.DATA


primearr BYTE 100 DUP(0)
onehalf DWORD ?
lastcheck DWORD 2
themover DWORD 2
theprime BYTE 10 dup(' '),0


.CODE
_start:
mov eax, lengthof primearr ;Get length of the array
mov edx, 0 ;For Division
mov ebx, 2 ;Move 2 to bl for division
div ebx ;Divide to know when to stop
mov onehalf, eax ;Store in OneHalf

mov edi, offset primearr ;Get address of primearr

add edi, 2 ;Make edi 2, the first prime

addagain: mov eax, themover ;Move the prime for multiples
add edi, eax ;Go to first prime, move by multiples of the prime
cmp edi, lengthof primearr ;check if x is bigger than the array
JA incagain ;if if it is
mov byte ptr [edi], 1 ;x is not prime, divisible by x
jmp addagain ;Keep going to end of array

incagain: mov eax, lastcheck ;Get ready to check if more than halfway
cmp eax, onehalf ;check to see if enough have been checked
JA startout ;enough have been checked
inc lastcheck ;increment to the number that was checked
mov eax, lastcheck ;move lastcheck to register
mov edi, eax ;set edi to lastcheck
;;;;;;;cmp byte ptr [edi], 0 ;check if lastcheck is prime
JNE incagain ;it's not

mov eax, lastcheck ;move lastcheck to register
mov themover, eax ;move al to themover to set the multiples
mov edi, eax ;move al to edi to begin next multiples
JMP addagain ;set the multiples

startout: mov edi, 2 ;begin outputing at 2, the first prime
outagain: cmp edi , lengthof primearr ;check if all numbers have been outputed
JA Quit ;they have, so quit
;;;;;;;;cmp byte ptr [edi], 0 ;check if prime
JE primeout ;it's prime so jump
inc edi ;go to next number
JMP outagain ;jump back to beginning of output section

primeout: mov eax, edi ;move edi to register
dtoa theprime, eax ;convert edi to ascii for output
output theprime ;output the prime number
inc edi ;go to next number
JMP outagain ;jump back to beginning of output section

Quit: ;nothing left to do, quit

INVOKE ExitProcess, 0

PUBLIC _start

END
Posted on 2004-10-06 17:53:52 by sjaguar13
Just use the data size specifier when you do a comparison between an immediate value and an address. The assembler has ho way to recognise the size of the data if you don't.


mov [edi], BYTE PTR 0

mov [edi], WORD PTR 0

mov [edi], DWORD PTR 0
Posted on 2004-10-06 19:50:05 by hutch--
sjaguar13
...

mov edi,offset primearr ; Get address of primearr
add edi,2 ; Make edi 2, the first prime
addagain:
mov eax,themover ; Move the prime for multiples
add edi,eax ; Go to first prime, move by multiples of the prime
cmp edi,lengthof primearr ; check if x is bigger than the array
;; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;; you compare the address and length
;; must compare index of element and length
...
mov eax,lastcheck ; move lastcheck to register
mov edi,eax ; set edi to lastcheck
;;;;;;;cmp byte ptr [edi], 0
;; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;; EDI contains index of element
;; must contains address
...
startout:
mov edi,2 ; begin outputing at 2, the first prime
outagain:
cmp edi,lengthof primearr ; check if all numbers have been outputed
JA Quit ; they have, so quit
;;;;;;;;cmp byte ptr [edi], 0 ; check if prime
;; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;; EDI contains index of element
;; must contains address
...
Posted on 2004-10-06 19:58:57 by P2M
Ohhhh....I was forgetting the primearr part, cmp primearr, 0
Posted on 2004-10-06 23:50:09 by sjaguar13