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