        # This version is based on performing pointer arithmetic in C.
        # While the C code behind this is tricky, it leads to fewer instructions
        # necessary to accomplish the same thing.
        .data
newline:
        .asciiz "\n"
myArray:
        .word 5 32 87 95 286 386
myArrayLength:
        .word 6

        .text
main:
        # C code:
        #
        # int myArray[] = {5, 32, 87, 95, 286, 386}
        # int myArrayLength = 6
        # int* p
        #
        # for (p = myArray: p < myArray + myArrayLength: p++) {
        #   print(*p)
        #   print("\n")
        # }

        # strictly speaking, we should do myArray + myArrayLength in the
        # loop, but a decent compiler will lift this out of the loop
        # (much as with the difference between print_array1.asm and the
        #  optimized print_array2.asm)
        
        # t0: p
        # t1: myArray + myArrayLength (len)

        # initialize variables
        la $t0, myArray

        la $t2, myArrayLength
        lw $t3, 0($t2)          # integer with length is in t3
        sll $t4, $t3, 2         # now in bytes
        la $t5, myArray
        add $t1, $t5, $t4       # t1 = myArray + myArrayLength

loop:
        # see if p < len
        slt $t2, $t0, $t1
        beq $t2, $zero, end_main  # if not, break out

        # dereference p, and print it out
        lw $a0, 0($t0)
        li $v0, 1
        syscall
        la $a0, newline
        li $v0, 4
        syscall
        
        # increment p.  This is by 4, as each word is four bytes.
        addi $t0, $t0, 4

        # restart loop
        j loop

end_main:
        # exit the program
        li $v0, 10
        syscall

        
