Is there any problem in this MIPS code? Like address out of the bounds? What the meaning of the code?

65 views Asked by At

Description:

The line of code "addi $t0, $t0, 4" plus the address of the $t0 for 4 byte every cycle, But the address space of the Array is limited. I think it will be out of bounds.

The code follows:

.data
array: .word   1,1,1
tmp: .word   0 : 25

.text

      .globl main
 main:
      la         $t0, array
      li         $t1,  25
loop: lw         $t3, 0($t0)  
            lw         $t4, 4($t0) 
            lw         $t5, 8($t0) 
            add        $t2, $t3, $t4  
            add        $t2, $t2, $t5 
            sw         $t2, 12($t0)    
            addi       $t0, $t0, 4  
            addi       $t1, $t1, -1  
            bgtz       $t1, loop    
            li     $v0, 10                    # system call for exit
      syscall

I hope someone could help me to explian the purpose of the code, and tell me the problem of the code. Or maybe it is right and there are some wrong understanding in my mind.

1

There are 1 answers

2
Erik Eidt On

What the meaning of the code?

That code is computing something similar to the 3-Fibonacci sequence, adding together 3 elements next to each other to produce the next.  It is first adding array[0], array[1], and array[2], and storing that in what would be array[3].  On the next iteration it will add array[1], array[2], and array[3] storing the result in array[4].  (I don't recognize the exact algorithm, maybe someone else can.)

Key to understanding this code is that it uses the tmp space, which is declared immediately after the array, to hold the results (and future sources as well, which is what makes it similar to fib).

That declaration tmp: .word 0:25 means repeat 0, 25 times, creating 25 words of storage initialized with 0s.  So, the address of array[3] is the same as the address of tmp[0].

In assembly language, labels are not variable declarations, they are location declarations, i.e. labels have values and their values are address constants.

So, unlike other languages, in assembly we can rely on this kind of juxta positioning — the author has effectively declared a storage block of 28 consecutive words, the first 3 of which are initialized (with 1's) and the rest are initialized with 0's.  The address of the first word of this storage is given to the label array — while the address of the fourth word of this storage is given to the label tmp.

The label tmp is both unused and unnecessary and could be removed (but the .word 0:25 must remain following the array line).

The last iteration of the loop will access array[24], array[25], and array[26], summing them together and storing in array[27].  Remember that array[27] is equivalent to tmp[24], which is also the last element of that 28 word block.

Like address out of the bounds?

No.  If you can appreciate that the storage declared in the data section is really one unit or block of 28 words, then you'll see that it the code does not reference out of the bounds of that declared storage.

The C language, does not offer guarantees of relative positioning of two variables.  So, declaring an array of 1's immediately followed by the storage of zeros:

int array[3]={1,1,1};
int tmp[25];

and then coding the same algorithm in C using the above storage declaration, it will perform access out of bounds (which C is not required to detect).  Also because there is no ordering requirement of variables in C, that code might "work" if the compiler follows declaration ordering — however, it involves undefined behavior.