In this project, the MIPS assembly language is used to find Prime Numbers. Annually, close to a hundred million MIPS-based processors are used in a wide range of products. Learning assembly language programming exposes one to not only the details of the instruction set, but also makes one aware of how compilers produce assembly/machine language code from a high-level language program. Assembly language programming is still used to write programs in which speed or size are critical or to exploit hardware features that have no analogues in high-level languages.

Here’s the code to find Prime Numbers in MIPS Assembly:

#*************************************** # Jason Weber, Nick Stumpos # #*************************************** .data .align 4 DONE: .asciiz "\nDone.\n " MSG4: .asciiz " " new_line: .asciiz "\n"; #---------------------------------------------------------------- # Procedure: main # 1. Iterate over the integers up to the 100th prime # 2. Uses test_prime to to test if each integer is prime # 3. Prints the first 100 numbers that are prime #---------------------------------------------------------------- .text .globl main main: add $fp, $zero, $sp; # set the frame pointer addi $s0, $zero, 0; # put 0 in s0 (number of primes found) addi $s1, $zero, 100; # put 100 in s1 (number were looking for) addi $s2, $zero, 0 # put 0 in s2 (number were checking) addi $s3, $zero, 10; # put 10 in s3 for various checks addi $s4, $zero, 100; # put 100 in s4 for various checks main_loop: beq $s0, $s1, main_loop_done; add $a0, $zero, $s2; # put number to test as first arg jal test_prime; # call test_prime function beq $v0, $zero, prime_continue; # was it false addi $s0, $s0, 1; # inc s0 (count of primes) sub $t0, $s2, $s3; bgez $t0, not_single; # is $s2 a single digit li $v0, 4; # print a space before the number la $a0, MSG4; syscall; not_single: sub $t0, $s2, $s4; bgez $t0, not_double; # is it a double or single digit li $v0, 4; # print a space before the number la $a0, MSG4; syscall; not_double: li $2,1; # system call code for print int add $4, $zero, $s2; # the prime number to be printed syscall; li $v0, 4; # print a space after the number la $a0, MSG4; syscall; div $s0,$s3; # is this a place for a newline mfhi $t0; bgtz $t0, prime_continue; # a mult of 10? li $v0, 4; # if so print a new line la $a0, new_line; syscall; prime_continue: addi $s2, $s2, 1; # inc s4(number to be tested) beq $zero,$zero, main_loop; # loop main_loop_done: li $v0, 4; # print done la $a0, DONE; syscall; li $v0, 10 # system call to exit syscall; #----------------------------------------------------- # Procedure: test_prime # Input: integer value n # Return: 1 if n is prime and 0 if n is not prime # # of the callee saved registers the subroutine test_prime uses # s2, s3 so we will save those to the stack # as well as the old fp, and return pointers in # the beginng and restore them in the end. # we will then set the new $fp to keep with convention # although we dont ever use it #--------------------------------------------------------- .text test_prime: addi $sp,$sp,-4; # dec sp sw $ra,($sp); # save return address on stack addi $sp,$sp,-4; # dec sp sw $fp,($sp); # save fp on stack addi $sp,$sp,-4; # dec sp sw $s2,($sp); # save s2 on stack addi $sp,$sp,-4; # dec sp sw $s3,($sp); # save s3 on stack addi $sp,$sp,-4; # dec sp addi $fp, $sp, 32 # set $fp addi $s2, $zero, 1 # put 1 in s2 bne $s2, $a0, not_one; # is the arg 1 add $v0, $zero, $zero # if so not a prime beq $zero, $zero, exit_prime # exit subroutine not_one: addi $s2, $zero, 2; # put immediate value 2 in s2 beq $a0,$s2, three_done; # two is a prime div $a0, $s2; # do divide mfhi $t0; # get remainder bgtz $t0, three; # is it a mult of 2 add $v0, $zero, $zero # if so not a prime beq $zero,$zero,exit_prime # exit subroutine three: addi $s2, $s2, 1; # put 3 in s2 three_loop: add $t0, $zero, $zero # clear reg mult $s2, $s2; # get $s2^2 mflo $s3; # get answer. for our purposes it will always be in the lo sub $t0, $a0, $s3; # is s2 greater than the squareroot of a0 bltz $t0, three_done; # if so were done div $a0, $s2; # do divide mfhi $t0; # get remainder bgtz $t0, three_cont; # is $a0 a mult of $s2 add $v0, $zero, $zero # if so not a prime beq $zero,$zero,exit_prime # exit subroutine three_cont: addi $s2, $s2, 2; # continue skipping mults of three and evens beq $zero, $zero, three_loop; # go again three_done: # through loop so number is a prime addi $v0, $zero, 1; # is prime so true exit_prime: addi $sp,$sp,4; # inc sp lw $s3,($sp); # get old s3 off stack addi $sp,$sp,4; # inc sp lw $s2,($sp); # get old s2 off stack addi $sp,$sp,4; # inc sp lw $fp,($sp); # get old fp off stack addi $sp,$sp,4; # inc sp lw $ra,($sp); # get return address off stack addi $sp,$sp,4; # inc sp back to where we expect it to start jr $ra; # go back to caller+4

## Post a Comment