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
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>