Thursday, May 21, 2020

Median of a sorted array in MIPS

This is a simple MIPS program that finds the median of a sorted array of integers. The code is fully explained and documented.

Launch EzMIPSthe MIPS assembler simulator, copy the following MIPS code and paste it into EzMIPS. Assemble, Run.

# --- Median of a sorted array of integer values of even length -- #
# ---------------------------------------------------------------- #

# median (for an even length array) = ( array[len/2] + array[len/2-1] ) / 2

# ----------------------- Data Declarations ---------------------- #
.data
array:  .word  1,  3,  5,  7,  9
        .word 11, 20, 25, 77, 89

length: .word 10
median: .word 0

# ------------------------- text/code section -------------------- #

.text

main:
    la $t0, array         # load starting address of the array into $t0
    lw $t1, length        # load the array length into $t1
    
    srl $t2, $t1, 1       # $t2 = length/2 = $t1/2 = $t1>>1 = 5

    # convert index into offset
    sll $t3, $t2, 2       # $t3 = $t2 * 4  = $t2<<2 = 20    
    
    # add base address of array to the offset
    add $t4, $t0, $t3     # $t4 = $t0 + $t3

    # get value of array[len/2]
    lw $t5, ($t4)         # $t5 = array[len/2]

    # address of previous value
    addi $t4, $t4, -4

    # get value of array[len/2-1]
    lw $t6, ($t4)         # $t6 = array[len/2-1]

    add $t7, $t6, $t5     # $t7 = array[len/2-1] + array[len/2]

    srl $t8, $t7, 1       # $t8 = $t7 /2 = $t7>>1
    sw $t8, median        # save median

    # .............................................................#

    # Done, terminate program
    li $v0, 10            # terminate
    syscall               # system call

# ---------------------------------------------------------------- #

Please let me know of any suggestions or bugs regarding the code above.

Regards,

Antonis

Wednesday, May 20, 2020

Store integer values in MIPS $gp memory

This is a simple MIPS program that stores arbitrary integer values in MIPS $gp memory (in ascending order). The code is fully documented.

Launch EzMIPSthe MIPS assembler simulator, copy the following MIPS code and paste it into EzMIPS. Assemble, Run.

# -------------- store integer values in $gp memory -------------- #

.text

# ................................................................ #
main:

ori $s0, $zero, 0x100           # $s0 = 0x100
sw $s0, 16($gp)                  # MEM[0x10008010]= 0x100

ori $s0, $zero, 0x1             # $s0 = 0x1
sw $s0, 0($gp)                  # MEM[0x10008000] = 0x1

ori $s0, $zero, 0x2             # $s0 = 0x2
sw $s0, 4($gp)                  # MEM[0x10008004] = 0x2

ori $s0, $zero, 0x1000          # $s0 = 0x1000
sw $s0, 20($gp)                 # MEM[0x10008014] = 0x1000

ori $s0, $zero, 0x10            # $s0 = 0x10
sw $s0, 8($gp)                 # MEM[0x10008008] = 0x10

ori $s0, $zero, 0x20            # $s0 = 0x20
sw $s0, 12($gp)                 # MEM[0x1000800c] = 0x20

# ................................................................ #

# Done, terminate program
li $v0, 10
syscall             # all done!

# ................................................................ #

Please let me know of any suggestions or bugs regarding the code above.

Regards,

Antonis

MIPS Heap Memory

This is a sample MIPS program that allocates heap memory and uses it to store several values entered by the user. The code is fully documented.

Launch EzMIPSthe MIPS assembler simulator, copy the following MIPS code and paste it into EzMIPS. Assemble, Run.

# ------ allocate heap memory and use it for storage in MIPS ----- #

.data
szEnterID:    .asciiz "Enter ID: "
szID:         .asciiz "ID: "

szEnterYear:  .asciiz "Enter Year: "
szYear:       .asciiz "Year: "

szEnterTitle: .asciiz "Enter Title: "
szTitle:      .asciiz "Title: "

szEnterNotes: .asciiz "Enter Notes: "
szNotes:      .asciiz "Notes: "

szValues:     .ascii "\n"
              .ascii  "Values stored in Heap memory:\n"
              .asciiz "-----------------------------\n"

szLF:         .asciiz "\n"

.text
# ................. Allocate heap memory of 384 bytes ............ #

    li $v0, 9            # allocate heap memory code
    li $a0, 384          # How much memory (in bytes) = 384
    syscall              # allocate it!
    move $s0, $v0        # store the address of our allocated memory
                         # in $s0

# ................................................................ #

    # print "Enter ID: "
    li $v0, 4            # print string code
    la $a0, szEnterID    # load address of szEnterID
    syscall              # print it!

    # Read integer 'ID' from user
    li $v0, 5            # read integer syscall code
    syscall              # do it!
    sw $v0, 0($s0)       # store ID into memory Offset: 0

# ................................................................ #

    # print "Enter Year: "
    li $v0, 4            # print string code
    la $a0, szEnterYear  # load address of szEnterYear
    syscall              # print it!

    # Read integer 'Year' from user
    li $v0, 5            # read integer syscall code
    syscall              # do it!
    sw $v0, 4($s0)       # store year into memory Offset: 4

# ................................................................ #

    # print string "Enter Title: "
    li $v0, 4            # print string code
    la $a0, szEnterTitle # load address of szEnterTitle
    syscall              # print it!

    # Read string 'Title' from user
    li $v0, 8            # read string
    addiu $a0, $s0, 8    # store 'Title' into memory Offset: 8
    li $a1, 64           # $a1 = maximum number of characters to read
    syscall

# ................................................................ #

    # print "Enter Notes: "
    li $v0, 4            # print string code
    la $a0, szEnterNotes # load address of szEnterNotes
    syscall              # print it!

    # Read string 'Notes' from user
    li $v0, 8            # read string
    addiu $a0, $s0, 72   # store 'Notes' into memory Offset: 72
    li $a1, 256          # $a1 = maximum number of characters to read
    syscall              # do it!

# ................................................................ #

    # print "Values read & stored in Heap memory:"
    #       "------------------------------------"
    li $v0, 4            # print string code
    la $a0, szValues     # load address of szValues
    syscall              # print it!

# ............................. ID ............................... #
    
    # print "ID: "
    li $v0, 4            # print string code
    la $a0, szID         # load address of szID
    syscall              # print it!


    # print integer 'ID'
    li $v0, 1            # print integer code
    lw $a0, 0($s0)       # Print the ID stored at $s0     [Offset: 0]
    syscall              # print it!
    
    # print "\n"
    li $v0, 4            # print string code
    la $a0, szLF         # load address of szLF
    syscall              # print it!

# ............................. Year ............................. #
    
    # print "Year: "
    li $v0, 4            # print string code
    la $a0, szYear       # load address of szYear
    syscall              # print it!
    
    # print integer 'Year'
    li $v0, 1            # print integer code
    lw $a0, 4($s0)       # Print the Year stored at $s0   [Offset: 4]
    syscall              # print it!
    
    # print "\n"
    li $v0, 4            # print string code
    la $a0, szLF         # load address of szLF
    syscall              # print it!

# ............................. Title ............................ #
    
    # print "Title: "
    li $v0, 4            # print string code
    la $a0, szTitle      # load address of szTitle
    syscall              # print it!

    # print string 'Title'
    li $v0, 4            # print string code
    addiu $a0, $s0, 8    # Print the Title stored at $s0 [Offset: 8]
    syscall              # print it!

    # print "\n"
    li $v0, 4            # print string code
    la $a0, szLF         # load address of szLF
    syscall              # print it!

# ............................. Notes ............................ #
    
    # print "Notes: "
    li $v0, 4            # print string code
    la $a0, szNotes      # load address of szNotes
    syscall              # print it!

    # print string 'Notes'
    li $v0, 4            # print string code       
    addiu $a0, $s0, 72   # Print description stored at $s0 [Offset: 72]
    syscall              # print it!

    # print "\n"
    li $v0, 4            # print string code
    la $a0, szLF         # load address of szLF
    syscall              # print it!

# ---------------------------------------------------------------- #

Please let me know of any suggestions or bugs regarding the code above.

Regards,

Antonis

Tuesday, May 19, 2020

MIPS power function

This is another sample MIPS program that computes the power of X^Y. In this program, X and Y are hardcoded variables that can be easiy changed for further testing. The code is fully documented.

Launch EzMIPSthe MIPS assembler simulator, copy the following MIPS code and paste it into EzMIPS. Assemble, Run.

# -------- Function to compute power (ie, X to Y power) -------- #

# --------------------- Data Declarations ---------------------- #
.data
X:        .word 4
Y:        .word 11
Answer:   .word 0

szTo:     .asciiz " ^ "
szEquals: .asciiz " = "
szLF:     .asciiz "\n"

# ------------------------- Main routine ----------------------- #

# Call simple procedure to add two numbers

.text

# ............................. main ........................... #

main:

    lw $a0, X               # pass argument to function
    lw $a1, Y               # pass argument to function
    jal power               # call power(int X, int Y) function
    sw $v0, Answer          # store result of power(int X, int Y)
                            # into Answer variable

# ............................ print ........................... #

# print integer X
    li $v0, 1              # print integer code
    lw $a0, X              # copy X to $a0
    syscall                # print it!

# print string " ^ "
    li $v0, 4              # print string code
    la $a0, szTo           # load address of szTo
    syscall                # print it!

# print integer Y
    li $v0, 1              # print integer code    
    lw $a0, Y              # copy Y to $a0
    syscall                # print it!

# print string " = "
    li $v0, 4              # print string code
    la $a0, szEquals       # load address of szEquals
    syscall                # print it!

# print integer answer
    li $v0, 1              # print integer code
    lw $a0, Answer         # copy Answer to $a0
    syscall                # print it!

# ............................ terminate ....................... #

    li $v0, 10
    syscall                # exit program

# ................... power(int X, int Y) function ............. #

# function to find and return X^Y

# Arguments
# $a0 – X
# $a1 – Y

# Returns
# $v0 = X^Y

power:
    li $v0, 1              # initialize $v0 = 1
    li $t0, 0              # initialize $t0 = 0

loop:
    mul $v0, $v0, $a0      # $v0 = $v0 * $a0 (remember $a0 = X)
    addi $t0, $t0, 1       # $t0 = $t0 + 1
    blt $t0, $a1, loop     # if $t0 < $a1, loop (remember $a1 = Y)
    jr $ra                 # return to caller (ie retutn to main()

# -------------------------------------------------------------- #

Please let me know of any suggestions or bugs regarding the code above.

Regards,

Antonis

Monday, May 18, 2020

MIPS sum of the array elements

This is another sample MIPS program that computes the sum of all array elements. The code is fully documented.

Launch EzMIPSthe MIPS assembler simulator, copy the following MIPS code and paste it into EzMIPS. Assemble, Run.

#-------------- Find the sum of the array elements ----------------#

# --------------------------- data ------------------------------- #
.data

elements: .word 12                               # nuber of array elements
array:    .word 3,   4,  7, 10, 15, 21           # array of numbers
          .word 23, 34, 67, 88, 99, 100

sum:      .word 0
szSumIs:  .asciiz "The sum of the array elements is = "
szLF:     .asciiz "\n"

#---------------------------- program -----------------------------#

.text

main:
    
    lw $s0, elements             # $s0 = nuber of array elements
    la $t0, array                # load the address of the array into $t0
    and $s1, $s1, $zero          # clear $s1 (keeps the running sum)

    # ........................ addition ...........................#
add_next:
    lw $t1, 0($t0)               # load the next value of the array
    add $s1, $s1, $t1            # add it to the running sum
    addi $t0, $t0, 4             # increment to the next address
    addi $s0, $s0, -1            # decrement the loop counter
    bne $0, $s0, add_next        # loop back until complete
    
    sw $s1, sum                  # store the final total

    # ....................... printing ............................#

    la $a0, szSumIs              # load address of szSumIs
    li $v0, 4                    # print string code
    syscall                      # print it!
    
    move $a0, $s1                # sum is kept in $s1, copy it to $a0
    li $v0, 1                    # print integer code
    syscall                      # print it!

    la $a0, szLF                 # load address of szLF
    li $v0, 4                    # print string code
    syscall                      # print it!

    # ..................... Exit program ..........................#

    li $v0, 10                   # syscall to exit cleanly
    syscall                      # Do it!

# ---------------------------------------------------------------- #

Please let me know of any suggestions or bugs regarding the code above.

Regards,

Antonis

Volume and surface area of a rectangular parallelepiped

This is a sample MIPS program that computes the volume and surface area of  a rectangular parallelepiped. Its sides are defined by the A, B and C variables the values of which can be edited to carry out further tests. The code is fully documented.

Launch EzMIPSthe MIPS assembler simulator, copy the following MIPS code and paste it into EzMIPS. Assemble, Run.

# ---------------------------------------------------------------- #

# Formulas used:
# Volume = A * B * C
# Surface Area = 2 * ( A * B + A * C + B * C)

# ...................... Data declarations ....................... #

.data

# A, B, and C sides are initialized to arbitrary integer values, edit as you wish
A: .word 4
B: .word 5
C: .word 6

V: .word 0    # Volume
S: .word 0    # Surface Area

szVolume: .asciiz "The volume is: "
szArea:   .asciiz "\nThe surface area is: "

# ....................... Text/code section ...................... #

.text

main:

    # ............................................................ #

    # Load variables into registers
    lw $t0, A
    lw $t1, B
    lw $t2, C
    
    # ............................................................ #

    # Find Volume of the rectangular parallelpiped
    # Volume = A * B * C
    
    mul $t3, $t0, $t1
    mul $t4, $t3, $t2
    
    sw $t4, V                   # store the Volume
    
    # ............................................................ #

    # Find Surface Area of the rectangular parallelepiped
    # Surface Area = 2*(A*B+A*C+B*C)

    mul $t3, $t0, $t1 # A * B
    mul $t4, $t0, $t2 # A * C
    mul $t5, $t1, $t2 # B * C
    add $t6, $t3, $t4
    add $t7, $t6, $t5

    sll $t7, $t7, 1             # equivalent to $t7 = $t7 * 2

    sw $t7, S                   # store the Surface Area
    
    # ............................................................ #

    la $a0, szVolume            # "The volume is: "
    li $v0, 4                   # print string code
    syscall                     # print it!

    la $a0, V                   # load address of V into $a0
    lw $a0, 0($a0)              # put value of V into $a0
    li $v0, 1                   # print integer code
    syscall                     # print it!

    la $a0, szArea              # "\nThe surface area is: "
    li $v0, 4                   # print string code
    syscall                     # print it!

    la $a0, S                   # load address of S into $a0
    lw $a0, 0($a0)              # put value of S into $a0
    li $v0, 1                   # print integer code
    syscall                     # print it!

    # ............................................................ #

    # Done, terminate program
    
    li $v0, 10                  # call code for terminate
    syscall                     # system call (terminate)

# ---------------------------------------------------------------- #

Please let me know of any suggestions or bugs regarding the code above.

Regards,

Antonis

Wednesday, May 13, 2020

Sum and integer average of array elements in MIPS

This is a sample MIPS program that computes the sum and the integer average for the elements of an array of integers. The code is fully documented.

Launch EzMIPSthe MIPS assembler simulator, copy the following MIPS code and paste it into EzMIPS. Assemble, Run.

# Compute the sum and integer average for the elements of an array #
# ---------------------------------------------------------------- #

# ---------------------- Data Declarations ----------------------- #

.data

array:       .word 21, 23, 25, 27, 29, 31, 33, 35, 37, 39
             .word 41, 43, 45, 47, 49, 51, 53, 55, 57, 90

array_size:  .word 20
sum:         .word 0
average:     .word 0

szSumIs:     .asciiz "The sum of 20 array elements is: "
szAverageIs: .asciiz "\nThe average 20 array elements is: "

# ---------------------------------------------------------------- #

# Basic approach:
# - loop through the array
# - access each value, update sum
# - calculate the average

.text

# ................................................................ #
main:
    lw $t2, array_size              # $t2 = array_size
    beq $t2, $zero, done            # if array size = 0, do not calulate anything!

    la $t0, array                   # $t0 = array starting address
    li $t1, 0                       # $t1 = loop index
    li $t3, 0                       # initialize sum, $t3 = 0

# Loop through the array to calculate sum
calc_sum:
    lw $t4, ($t0)                   # get array[i]
    add $t3, $t3, $t4               # sum = sum + array[i]

    addi $t1, $t1, 1                # i = i+1
    addi $t0, $t0, 4                # update array address (each word is 4 bytes)

    blt $t1, $t2, calc_sum          # if i<length, continue
    sw $t3, sum                     # save sum

# ...................... calculate average ....................... #

    div $t3, $t2                    # $lo = $t3/$t2 = sum/array_size
    mflo $t5                        # move integer average to $t5
    sw $t5, average                 # save average

done:
# ................................................................ #
    la $a0, szSumIs
    li $v0, 4
    syscall                         # print "The sum of 20 array elements is: "

    la $a0, sum
    lw $a0, 0($a0)
    li $v0, 1                       # print integer
    syscall                         # print it!

    la $a0, szAverageIs             # print "\nThe average 20 array elements is: "
    li $v0, 4
    syscall

    la $a0, average
    lw $a0, 0($a0)
    li $v0, 1                       # print integer
    syscall                         # print it!

    # Done, terminate program
    li $v0, 10                      # terminate
    syscall                         # system call

# ---------------------------------------------------------------- #

Please let me know of any suggestions or bugs regarding the code above.

Regards,

Antonis

Tuesday, May 12, 2020

Print the average of integers in float format

This is a sample MIPS program that asks the user to enter as many integer numbers as he wishes, calculates their average and prints it in float format. The code is fully documented.

Launch EzMIPSthe MIPS assembler simulator, copy the following MIPS code and paste it into EzMIPS. Assemble, Run.

# ---------------------------------------------------------------- #

# 1. User is asked to enter an integer number
# 2. if number inputted = 0, print how many numbers the User entered and their average
# 3. else, goto 1

.data
szEnterNumber:        .asciiz "Enter a Number (0 to exit): "
szTheSumIs:           .asciiz "\nThe sum is: "
szNumbersWereEntered: .asciiz " numbers were entered\n"
szLF:                 .asciiz "\n"
szTheAverageIs:       .asciiz "\nThe average is: "
szDecimalPoint:       .asciiz "."

# ................................................................ #

.text


main:
    nop

# ................................................................ #

# $t0 = counts how many numbers the user inputted
# $t1 = holds the sum of the numbers entered

start:                        # Loops until the user inputs a zero

    la $a0, szEnterNumber        # Loads the address of szEnterNumber into $a0
    li $v0, 4                    # System call code to print a string
    syscall                      # Print string
    
    li $v0, 5                    # System call code that reads an integer
    syscall                      # Reads the integer that the user had inputted
                                 # and puts it into $v0

    addi $t0, $t0, 1             # Increment the integer counter by 1
    add $t1, $t1, $v0            # Add the recently inputted integer to the current sum

    bne $v0, $zero, start        # Branch if the integer not equals zero

    addi $t0, $t0, -1            # since user inputted a 0,
                                 # numbers_entered = numbers_entered -1

# ..... User inputted a 0, calulate and print the results ........ #

    la $a0, szTheSumIs           # Loads the address of szTheSumIs into $a0
    li $v0, 4                    # System call code to print a string
    syscall                      # Print sum_mess.
    
    move $a0, $t1                # Moves the sum in $t1 into the argument register
    li $v0, 1                    # System call code to print an integer
    syscall                      # Prints the sum

    la $a0, szLF                 # Loads the address of szLF into the argument register
    li $v0, 4                    # System call code to print a string
    syscall                      # Print new line
    
    move $a0, $t0                # Moves the number of integers in $t0 into $a0
    li $v0, 1                    # System call code to print an integer
    syscall                      # Prints the number of integers that were inputted

    la $a0, szNumbersWereEntered # Loads the address of szNumbersWereEntered into $a0
    li $v0, 4                    # System call code to print a string
    syscall                      # Prints szNumbersWereEntered
    
    la $a0, szTheAverageIs       # Loads the address of szTheAverageIs into $a0
    li $v0, 4                    # System call code to print a string
    syscall                      # Prints szTheAverageIs
    
    jal average                  # Jump and link to average
    
    move $a0, $t2                # Move the value of $t2 into $a0
    li $v0, 1                    # System call code to print an integer
    syscall                      # Print the integer
    
    la $a0, szDecimalPoint       # Loads the address of szDecimalPoint into $a0
    li $v0, 4                    # System call code to print a string
    syscall                      # Prints szDecimalPoint
    
    move $a0, $t5                # Move the value of $t5 (the decimal value) to $a0
    li $v0, 1                    # System call code to print an integer
    syscall                      # Print the decimal value

# ................................................................ #

exit:    

    li $v0, 10                   # System call code to exit the program
    syscall                      # Exit the program

# .................. Calculate the average ....................... #

average:

    div $t1, $t0                 # Divide the sum in $t1 by $t0 (numbers_entered)
    mflo $t2                     # Store the quotient in $t2
    mfhi $t3                     # Store the remainder in $t3

    # ......... Convert remainder into decimal part .............. #
    li $t4, 1000                 # Stores the immediate value 1000 in $t4
    mult $t4, $t3                # Multiply the remainder by 1000
    mflo $t5                     # Store the product in $t5
    div $t5, $t0                 # Divide $t5 by the number of integers 
    mflo $t5                     # and store the result in $t5
    # ......... Convert remainder into decimal part .............. #
    
    jr $ra                       # Return to the caller

# ................................................................ #

Please let me know of any suggestions or bugs regarding the code above.

Regards,

Antonis