i break things...

fun with MIPS

so i’m programming in MIPS now — its pretty fun but its a huge bitch in general since MIPS is RISC (and probably the most popular RISC platform).

I’ve actually been good and not been writing everything in C first and then just gcc -S file — and seeing what the ASM looks like from that since i’m actually interested in learning more about ASM programming.

i’ve found it to be rather soothing once i’ve written it out on paper (its mad hard to do just by sitting at a terminal without prior pictures and stuff like that) — the last worthy program was a insertion sort for class — i seperated it into the two loops : namely the outer for look for incrementing I and the inner while loop to do the work…

i’ll be adding a print function for this over the weekend so i don’t have to read the damned registers for proper feedback

EDIT: print added!

# isort  jt  2009-01-23
# this program implements insertion sort -- it is broken up
# into several subroutines for readabliity and proper design
# its purpose is to sort an array and has been designed from
# this C algorithm by hand:
##############################################################################################
# include

# void isort(int a[], int asize) {
# int j, tmp;
# for (int i = 1; i # j = i;
# tmp = a[i];
# while ((j > 0) && (a[j-1] > tmp)) {
# a[j] = a[j-1];
# j--;
# }
# a[j] = tmp;
# }
# }

# int main()
# {
# int a[2];
# a[0] = 2;
# a[1] = 3;

# isort(a,2);

# }
##############################################################################################
# Register USE in main:
# $a0 : start addy of array
# $a1 : size of the array
##############################################################################################

.data
array: .word -3, 32, -1115, 4, 55, 21, 23, 0 # 8 element array
endarr:
size: .word 8 # size of the array

PR_INT = 1 #print int for int
PR_STR = 4 #print int for string
SIZE = (endarr - array) / 4 # slicker size

print_array: .asciiz "the array in order is : "
space: .byte ' '

.text
.align 2

.globl main
main:
la $a0, array # load the start addy
lw $a1, size # $a1 gets the size
jal isort # jump to isort
li $v0, PR_STR # print string
la $a0, print_array# introduction string for array
syscall # syscall
jal print # printing function
li $v0, 10 # function for exit for syscall
syscall
end_main:

##############################################################################################
### isort subroutine
### main jumps to this routine in order to sort the array
### this subroutine handles the exterior for loop
###
### Register USE:
### $a0 : pointer to array start
### $a1 : size of the array in words
### $a2 : steps back from unsorted value to be inserted
### $s0 : gets addr of start of the array
### $s1 : j
### $s2 : unsorted value to be inserted
##############################################################################################

isort:
addi $sp, $sp, -20 # start stack -- make room for ret val
sw $ra, 4($sp) # push ret val on stack
sw $s0, 8($sp) # store important $s* registers
sw $s1, 12($sp) # " " "
sw $s2, 16($sp) # " " "

move $s0, $a0 # start of the array goes to $s0
addi $s1, $a1, -1 # this is j ... j = i-1

for:
li $s2, 1 # $s2 is where we pull the first unsorted value
for_compare:
bgt $s2, $s1, end_for #
for_body:
move $a0, $s0 # i = 0
mul $t1, $s2, 4 # indexify
add $t1, $t1, $s0 # start plus index
lw $a1, 0($t1) # load first unsorted index into $a1
addi $a2, $s2, -1 # decreement unsorted value index
jal insert # jump to insert subroutine

addi $s2, $s2, 1 # increment
j for_compare # jump to comparison
end_for:

lw $ra, 4($sp) # restore ret val to $ra
lw $s0, 8($sp) # reload values
lw $s1, 12($sp) # "
lw $s2, 16($sp) # "
lw $s3, 20($sp) # "

addi $sp, $sp, 20 # pop frame from stack
jr $ra
end_isort:

###############################################################################################
### insert subroutine assists isort in doing its job because it handles inserting with vars :
### element to insert, first sorted index, and testing index for insertion
### Register USE:
### # $a0 : base addy of the array
# # $a1 : element to be inserted
# # $a2 : element of the first sorted index
#
###### TEMPS used for the test index for insertion
# # $t0 : test index for insertion
# # $t1 : ''''''''''''''''
# # $t2 : test element
# # $t3 : plays nicely with a[j]
###############################################################################################
insert:
move $t0, $a2 # $t0 gets test index
while:
blt $t0, $0, end_while # while
AND: mul $t1, $t0, 4 # sll for index
add $t2, $a0, $t1 # base + index
lw $t3, 0($t2) # $t3 ble $t3, $a1, end_while # while not at end of array
while_body:
sw $t3, 4($t2) # a[j] = a[j-1]
addi $t0, $t0, -1 # j--
j while # ret while
end_while:
addi $t0, $t0, 1 # test_element ++
mul $t1, $t0, 4 # indexify
add $t2, $a0, $t1 # start + insert element index
sw $a1, 0($t2) # array[test_element] (gets) insert element
jr $ra # call to ret val
end_insert:

#########################################################################################


# sumar.asm james toy 20090115
# this program takes an array and sums up the values in that array
# REGISTERS USED
# $t0 -- starting address of the array and the pointer that walks it for summing
# $t1 -- end of the array
# $t3 -- in the loop -- its storing data from $t0
# $t3 -- accumulator
# $v0 -- print call

print:
la $t0, array # load the addy of the start of the array
la $t1, endarr # load the addy of the end of the array
print_loop:
li $v0, PR_STR
la $a0, space
syscall
li $v0, PR_INT
lw $a0, 0($t0)
syscall
addiu $t0, $t0, 4 # increment by 4 bytes to next int
bne $t0, $t1, print_loop # while the pointer != to end go back to loop
jr $ra # return control to simulator