Thursday, June 4, 2020

Sum of N integers using int add_function(int num1, int num2)

This is a simple MIPS program that computes the sum of N integers using the
int add_function(int num1, int num2). The function preserves the register involved in the addition ($s0) by putting it into the stack. The code is fully explained and documented.

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

#   Sum of N integers: 1 + 2 + ... + N using 'int add_function(int num1, int num2)'   #
# ---------------------------------------------------------------- #

# Notes:
# $s0 = number of integers (N)
# $s1 = counter (i)
# $s2 = sum

# ........................ data segment ......................... #   

.data
szEnterN:    .asciiz "Enter number of integers (N):"
szSumEquals: .asciiz "Sum = "
szLF:        .asciiz "\n"

# ........................ text segment .......................... #

.text

main:

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

    # Print "Enter number of integers (N):"
    li $v0, 4                      # print_string syscall code = 4
    la $a0, szEnterN    
    syscall

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

    # Get N from user and save in $s0
    li $v0, 5                      # read integer syscall code = 5
    syscall                        # read it!
    move $s0, $v0                  # syscall results returned in $v0,

# ............................................................... #                                        # save in $s0 (=N) for later use

    # Initialize registers
    li $s1, 0                      # $s1 = counter (i)
    li $s2, 0                      # $s2 = sum

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

loop:

    move $a0, $s2                  # Argument 1: sum ($s2)
    addi $a1, $s1, 1               # Argument 2: = $s1 + 1

    jal add_function               # Save current PC in $ra, and jump to add_function
    move $s2, $v0                  # Return value saved in $v0. This is sum ($s2)

    addi $s1, $s1, 1               # i = i + 1
    bne $s0, $s1, loop             # if i = N, continue

# ............. Print & exit program gracefully .................. #

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

    # Print integer sum
    li $v0, 1                      # print integer syscall code = 1
    move $a0, $s2                  # copy sum into $a0
    syscall                        # print it

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

    li $v0, 10                     # exit syscall code
    syscall                        # Exit!

# int add_function(int num1, int num2) ........................... #

# Argument int num1 is stored in $a0
# Argument int num2 is stored in $a1
# Return value is stored in $v0
# Return address is stored in $ra (put there by jal instruction)
    
add_function:

    # 1. Store register $s0 that we will overwrite into the stack
    addi $sp, $sp, -4              # Adjust stack pointer
    sw $s0, 0($sp)                 # Save $s0 on the stack

    # 2. Run the function (ie perform the addition)
    add $s0, $a0, $a1              # sum = sum + i

    # 3. Save the return value (addition result) into $v0
    move $v0, $s0

    # 4. Restore overwritte register($s0) from the stack
    lw $s0, 0($sp)
    addi $sp, $sp, 4               # Adjust stack pointer
    
    # 5. Jump to the caller's location (stored in $ra), ie return from function
    jr $ra                         # Jump to address stored in $ra
    
# ................................................................ #


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

Regards,

Antonis

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