c code
while (save[i]==k)
i+=1;
put i in $s3, k in $s5 and address of k in $s6
mips code
loop: sll $t1, $s3, 2
add $t1, $t1, $s6
lw $t0, 0($t1)
bne $t0, $s5, Exit
addi $s3, $s3, 1
j loop
Exit:
Your save array/pointer must be of some 4-byte type (ints?). Therefore to load save[i] from memory, the index i needs to be translated to a byte offset within the array, and then added to the base address of that array. This is done by multiplying i by four:
sll $t1, $s3, 2
and then adding save:
add $t1, $t1, $s6
This doesn't look like an optimized build though. Usually the compiler can re-write this code to advance a temporary pointer in increments of four directly, thus avoiding two of the instructions in that loop.
I am trying to achieve the following via MIPS assembly:
for(int i=0; i<n ; ++i){
arr2[i] = arr1[i];
}
$t2 stores the address of starting point of arr1 and $t3 stores the starting point of arr2
$t1 stores the value n upto which the loop runs.
My assembly code is as follows:
#save the value of $t2 and $t3
move $t8, $t2
move $t9, $t3
#init i=0
move $s7, $zero
copyArrayLoop: beq $s7, $t1, endCopyLoop
sw $t2, 0($t3)
addi $t2, $t2, 4
addi $t3, $t3, 4
addi $s7, $s7, 1
j copyArrayLoop
endCopyLoop: move $t2, $t8
move $t3, $t9
however, this copies the address of values stored at $t2 as it increments, and not the value in memory at address denoted by $t2, can anyone point what's going wrong here?
I have an array like this:
r_clues: .word 0 : 512 # array full of zero
I do
la $s0, r_clues
lw $t1, 0($s1)
and I take the address of first 4 bytes and if i want to take, for example, 4th address i will do
lw $t1, 16($s1)
because its 4(address) * 4(bytes)
How i can access to this array with one loop and load word to a register for each 8 bytes ?
Calculate address of elements and load words.
la $s0, r_clues # the address
addiu $s2, $zero, 0 # offset
addiu $s3, $zero, 64 # number of loops
loop_begin:
addu $s1, $s0, $s2 # address = base + offset
lw $t1, 0($s1) # load the array
addiu $s2, $s2, 8 # proceed to the next element
addi $s3, $s3, -1 # substract the counter
bne $s3, $zero, loop_begin # if there are more elements to load, go to loop
nop # prevent next instruction from being executed before exiting the loop
I was trying to convert C code to MIPS assembly. There are these two following C code snippets. The problem is that my solution differs from the standard solution. Also, I don't understand the standard solution. I hoped, someone could explain me the two following mips assembly code snippets.
First of all some additional information for the task. Only the following MIPS instructions are allowed: lw, add, beq, bne and j.
The register:
$s3 contains i
$s4 contains j
$s5 contains k
A is an array of 32-Bit-Integer and the initial address of A is in $s6
$t0 and $t1 can be used for storing temporary variables
The first one is a simple do-while loop:
do {
i = i + j;
} while(A[i] == k);
MIPS Assembly
loop: add $s3, $s3, $s4 // this is i = i+j
add $t1, $s3, $s3 // from now on
add $t1, $t1, $t1 // I cant follow anymore
add $t1, $t1, $s6 // What happens in these three lines?
lw $t0, 0($t1) // 0($t1) is new for me. What does this zero do?
beq $t0, $s5, loop
Now the second C code:
if ( i == j )
i = i + A[k];
else if( i == k )
i = i + A[j];
else
i = i + k;
Here is the MIPS assembly code:
bne $s3, $s4, Else1 // this line is if(i==j)
add $t1, $s5, $s5 // from here on
add $t1, $t1, $t1 // till
add $t1, $t1, $s6 //
lw $t0, 0($t1) //
add $s3, $s3, $t0 // here I don't understand
j done
ELSE1: bne $s3, $s5, Else2 // this line is if(i==k)
add $t1, $s4, $s4 // The same game as above
add $t1, $t1, $t1
add $t1, $t1, $s6
lw $t0, 0($t1)
add $s3, $s3, $t0 // till here
j done
ELSE2: add $s3, $s4, $s5
Could anyone explain me what really goes on? That would be very helpful
O.k. the most interesting and not-understandable piece of code is the following:add $t1,
add $t1, $s5, $s5
add $t1, $t1, $t1
add $t1, $t1, $s6
this code multiplies $s5 by four, and stores it in $t1, then adds to $t1 $s6. That is equivalent to:
$t1 = A[k]
after you understand this, the code looks much clearer.
about the lw $t0, 0($t1):
you can use an offset point in the address. Here the offset is 0.
lw is load. The mode here is indirect addressing, the most common is:
lw $t2, ($t0)
But you can also include a byte offset,
lw $t2, 4($t0) # load word at RAM address ($t0 + 4) into register $t2
The compiler is just putting the 0 placeholder in the non-offset version.
So, to load A[i] you need to do two things. Take the base address of A[] and then add i times the sizeof(A[0]). I am guessing that the values in A are 32 bit.
add $t1, $s3, $s3
$t1 = j + j or 2 * j
add $t1, $t1, $t1
$t1 = $t1 + $t1 or j +j +j +j or 4 * j
So why did it do it this way? Well, doing a straight multiply is slow in terms of clock cycles. The next choice would be a shift operation, but in this case, the compiler designers decided that two adds beat a shift.
add $t1, $t1, $s6
I would guess that $s6 is the base address of A[]. So ultimately '$t1 = A[] + 4 * j`
I have a answer.The loop, a is array of elements have basic address :0x0FE3B128.
Thanks all so much..
and this is my homework, I don't sure that it is correct.
for(i=1; i!=20;i+=3){
a[i]= a[5]+1;
}
lui $s0, 0x0FE3
ori $s0, $0, B128
lw $t1, 20($s0)
addi $s1, $0, 1
addi $s2, $0, 20
LOOP beq $s1, $s2, DONE
add $t1, $t1, $s1
sll $t1, $t1, 2
sw $t2, 0($t1)
addi $s1, $0, 3
j LOOP
DONE
okay, C++ and java i have no problem learning or what so ever
when it comes to mips it is like hell
okay i wanna learn how to read in the an array and print all the element out
here is a simple array that i wrote
int[] a = new int[20];
for(int i=0; i<a.length; i++){
a[i]=1;
}
for(int j=0; j<a.length; j++){
System.out.Println(a[i])
}
how do you do it in mips
Assuming that you have your array address at register $a1, you can do the following:
li $t0, 1
move $t1, $a1
addi $t2, $a1, 80
loop1:
sw $t0, ($t1)
addi $t1, $t1, 4
bne $t1, $t2, loop1
move $t1, $a1
loop2:
lw $t0, ($t1)
li $v0, 1
move $a0, $t0
syscall
addi $t1, $t1, 4
bne $t1, $t2, loop2
This code should produce the same result as your java code, except that you used println (which will print each element in a new line) and this code will print all the elements of the array in the same line.
I don't know if you have noticed, but your Java code and this code will print all 1s, if you want to print numbers from 1 to 19, you will have to increment $t0, inside loop1