Assemble Your Primes

In todays code example we are going to look at a bit of code in MASM Assembly that calculates a series of prime numbers up to a user given value. Enjoy.

TITLE Lab7 - No Calculus Primes! (Lab7.asm)
 
; Program Description: Calculate the first 1000 or so prime numbers
; Author: Bob Chatman
; Date: Nov. 20, 2008
 
INCLUDE Irvine32.inc
 
UPPERLIMIT		EQU 7919
NUMELEMENTS		EQU 999
FIRSTELEMENT	EQU 5
SIZEOFDATA		EQU 4
NUMPERLINE		EQU 10
 
.stack                   
 
.data
space				BYTE " "					, 0
upperLimitPrompt	BYTE "Upper Limit: "		, 0
upperLimitError		BYTE "Resetting to "		, 0
headerString		BYTE "The Primes are... "	, 0
 
primes				WORD 2, 3, NUMELEMENTS DUP(0)
 
StringOut MACRO s
 
    push EDX				; Save the EDX register
    mov EDX, OFFSET s		; Move the address in
    call WriteString		; Call the procedure to write it
    pop EDX					; Revert EDX
 
ENDM
 
IntOut MACRO i
 
    push EAX				; Save the EAX register
    mov EAX, i				; Move in the value
    call WriteDec			; Call the procedure to write it
    pop EAX					; Revert EAX
    StringOut space			; Output a space
 
ENDM
 
.code
main PROC
 
	; Reserve space for return value
    push OFFSET primes
    sub ESP, 4            
 
    call GetLimit
    call GenPrimes
 
    ; Dont need this returned variable any more
    add ESP, 4            
 
    call PrintPrimes
 
    exit
 
main ENDP
 
GetLimit PROC
 
    ; Set up the stack
    push EBP
    mov EBP, ESP
 
    ; Push Registers onto the stack
    push EAX
 
    ; Output the prompt and get the input
    StringOut upperLimitPrompt   
    call ReadDec
 
    ; Make sure the input is within the limit   
    cmp EAX, UPPERLIMIT
    jbe GOODINPUT   
 
    ; Output an error message that we are changing the value
    StringOut upperLimitError
    IntOut UPPERLIMIT
    call CRLF
 
    ; Cant copy to the stack from immediate b/c of Immediate to memory issues
    mov EAX, UPPERLIMIT            
    GOODINPUT:
 
	; Put the return value here
    mov [EBP + 8], EAX
 
	; Revert used registers
    pop EAX
    pop EBP
 
    ret
GetLimit ENDP
 
GenPrimes PROC
 
    ; Set up the stack, Again
    push EBP
    mov EBP, ESP
 
    ; Push Registers onto the stack
    push ECX
    push EBX
    push EAX
    push EDX
    push ESI
 
	; Setup our calculations   
    mov CX, FIRSTELEMENT	; Start at 5
    mov EBX, [EBP + 12]		; Get the address of the array
    mov ESI, EBX			; Duplicate the EBX register 
    add ESI, SIZEOFDATA		; Increment ESI to next open spot
 
    NEEDMOAR: 
 
    DIVIDE:
    add EBX, 2				; Increment to next element [Begins at 3]
    mov AX, CX				; Revert AX to our test value
    mov DX, 0				; Clear out DX register for division
    div WORD PTR [ebx]		; Do some cool division
    cmp DX, 0				; Check the remainder
    JE NEXTNUMBER			; if its a clear division, jump
    cmp AX, WORD PTR [ebx]	; Compare the dividend to the divisor
    JA DIVIDE				; If its larger, jump and do again
 
    ; Add this value to our array and increment the walker register
    mov [ESI], CX			
    add ESI, 2
 
	; Revert and increment our registers for the next pass. 
    NEXTNUMBER:	
    mov EBX, [EBP + 12]		
    add CX, 2
    cmp CX, [EBP + 8]		
    JBE NEEDMOAR			; Do we need more values?
 
	; Revert used registers
    pop ESI
    pop EDX
    pop EAX
    pop EBX
    pop ECX
    pop EBP
 
    ret
GenPrimes ENDP
 
PrintPrimes PROC
 
    ; Set up the stack, Again, Again
    push EBP
    mov EBP, ESP
 
    ; Push Registers onto the stack
    push EAX
    push EBX
    push ECX
 
    StringOut headerString
    call CRLF
 
    ; Setup registers
    mov ECX, NUMPERLINE
    mov EBX, [EBP + 8]
    mov EAX, 0
    mov AX, [EBX]
 
    NEXTELEMENT:
 
    IntOut EAX
 
    ; Check the counter value
    dec ECX
    cmp ECX, 0
    jne NONEXTLINE	
 
    ; Revert the counter and call new line
    mov ECX, NUMPERLINE
    call CRLF
 
    NONEXTLINE:
 
	; Increment to the next element and check the value
    add EBX, 2
    mov AX, [EBX]
    cmp AX, 0
    jg NEXTELEMENT
 
	; Revert used registers
    pop ECX
    pop EBX
    pop EAX   
    pop EBP
 
    ret
PrintPrimes ENDP
 
END main

Leave a Reply

Spam Protection by WP-SpamFree

Using Gravatars in the comments - get your own and be recognized!

XHTML: These are some of the tags you can use: <a href=""> <b> <blockquote> <code> <em> <i> <strike> <strong>