This is a sample MIPS program that loops 10 times and with each iteration it calls the 'print_integer(int num)' subroutine. The 'print_integer(int num)' subroutine prints "The number is n", where n is the argument passed in $a0. Care has been taken to preserve local variables. The code is fully documented.
Launch EzMIPS, the MIPS assembler simulator, copy the following MIPS code and paste it into EzMIPS. Assemble, Run.
# ---------------------------------------------------------------- #
.data
count: .word 10
szTheNumberIs: .asciiz "The number is "
szLF: .asciiz "\n"
# ---------------------------------------------------------------- #
.text
# ................................................................ #
jal main # after executing, $ra will be equal to 0x00400004
li $v0, 10
syscall # exit program
# ................................................................ #
main:
# ............. Adjust stack ($sp = 0x7fffefdc) .............. #
addiu $sp, $sp, -32
# ............. Adjust stack ($sp = 0x7fffefdc) .............. #
sw $ra, 24($sp) # (0x7fffefdc + 24) = (0x7fffeff4) = 0x00400004
sw $fp, 16($sp) # save old frame pointer, (0x7fffefec) = $fp = 0
addiu $fp, $sp, 28 # load new frame pointer
# ie $fp = 0x7fffefdc + 28 = 0x7fffeff8
# ............................................................ #
la $t0, count
lw $t1, 0($t0) # $t1 = 10
li $t0, 0 # init index to 0
loop:
sw $t0, 12($sp) # save caller saved registers (0x7fffefe8) = $t0
# 0, 1, 2, 3, ... , 9
sw $t1, 8($sp) # (0x7fffefe4) = $t1 = 10 = 0xa
move $a0, $t0 # setup parameter for function call
# ie $a0 = 0, 1, 2, 3, ... , 9
jal print_integer # call subroutine
# restore caller saved values
lw $t1, 8($sp) # ie $t1 = (0x7fffefe4) = 10 = 0xa
lw $t0, 12($sp) # ie $t0 = (0x7fffefe8) = 0, 1, 2, 3, ... , 9
addiu $t0, $t0, 1 # increment index; ($t0++;)
blt $t0, $t1, loop # loop if $t0 < 10
# ............................................................ #
lw $fp, 16($sp) # restore frame pointer
lw $ra, 24($sp) # restore return address
# ............ Restore stack ($sp = 0x7fffeffc) .............. #
addiu $sp, $sp, 32 # restore stack pointer
# ............. Restore stack ($sp = 0x7fffeffc) ............. #
jr $ra
# ................................................................ #
print_integer:
# ............. Adjust stack ($sp = 0x7fffefbc) .............. #
addiu $sp, $sp, -32
# ............. Adjust stack ($sp = 0x7fffefbc) .............. #
sw $fp, 16($sp)
sw $s0, 12($sp)
addiu $fp, $sp, 28
move $s0, $a0 # store argument in temp variable
li $v0, 4
la $a0, szTheNumberIs # point to "This number is "
syscall # print string syscall
li $v0, 1
move $a0, $s0 # restore argument $a0
syscall # print integer syscall
li $v0, 4
la $a0, szLF # point to "\n"
syscall # print string syscall
lw $s0, 12($sp)
lw $fp, 16($sp)
# ............. Restore stack ($sp = 0x7fffefdc) ............. #
addiu $sp, $sp, 32
# ............. Restore stack ($sp = 0x7fffefdc) ............. #
jr $ra # jump to return address
# ---------------------------------------------------------------- #
Launch EzMIPS, the MIPS assembler simulator, copy the following MIPS code and paste it into EzMIPS. Assemble, Run.
# ---------------------------------------------------------------- #
.data
count: .word 10
szTheNumberIs: .asciiz "The number is "
szLF: .asciiz "\n"
# ---------------------------------------------------------------- #
.text
# ................................................................ #
jal main # after executing, $ra will be equal to 0x00400004
li $v0, 10
syscall # exit program
# ................................................................ #
main:
# ............. Adjust stack ($sp = 0x7fffefdc) .............. #
addiu $sp, $sp, -32
# ............. Adjust stack ($sp = 0x7fffefdc) .............. #
sw $ra, 24($sp) # (0x7fffefdc + 24) = (0x7fffeff4) = 0x00400004
sw $fp, 16($sp) # save old frame pointer, (0x7fffefec) = $fp = 0
addiu $fp, $sp, 28 # load new frame pointer
# ie $fp = 0x7fffefdc + 28 = 0x7fffeff8
# ............................................................ #
la $t0, count
lw $t1, 0($t0) # $t1 = 10
li $t0, 0 # init index to 0
loop:
sw $t0, 12($sp) # save caller saved registers (0x7fffefe8) = $t0
# 0, 1, 2, 3, ... , 9
sw $t1, 8($sp) # (0x7fffefe4) = $t1 = 10 = 0xa
move $a0, $t0 # setup parameter for function call
# ie $a0 = 0, 1, 2, 3, ... , 9
jal print_integer # call subroutine
# restore caller saved values
lw $t1, 8($sp) # ie $t1 = (0x7fffefe4) = 10 = 0xa
lw $t0, 12($sp) # ie $t0 = (0x7fffefe8) = 0, 1, 2, 3, ... , 9
addiu $t0, $t0, 1 # increment index; ($t0++;)
blt $t0, $t1, loop # loop if $t0 < 10
# ............................................................ #
lw $fp, 16($sp) # restore frame pointer
lw $ra, 24($sp) # restore return address
# ............ Restore stack ($sp = 0x7fffeffc) .............. #
addiu $sp, $sp, 32 # restore stack pointer
# ............. Restore stack ($sp = 0x7fffeffc) ............. #
jr $ra
# ................................................................ #
print_integer:
# ............. Adjust stack ($sp = 0x7fffefbc) .............. #
addiu $sp, $sp, -32
# ............. Adjust stack ($sp = 0x7fffefbc) .............. #
sw $fp, 16($sp)
sw $s0, 12($sp)
addiu $fp, $sp, 28
move $s0, $a0 # store argument in temp variable
li $v0, 4
la $a0, szTheNumberIs # point to "This number is "
syscall # print string syscall
li $v0, 1
move $a0, $s0 # restore argument $a0
syscall # print integer syscall
li $v0, 4
la $a0, szLF # point to "\n"
syscall # print string syscall
lw $s0, 12($sp)
lw $fp, 16($sp)
# ............. Restore stack ($sp = 0x7fffefdc) ............. #
addiu $sp, $sp, 32
# ............. Restore stack ($sp = 0x7fffefdc) ............. #
jr $ra # jump to return address
# ---------------------------------------------------------------- #
Please let me know of any suggestions or bugs regarding the code above.
Regards,
Antonis
No comments:
Post a Comment