Copying elements from one array to another in MIPS assembly - arrays

I'm new at MIPS and have been trying to copy elements from one array to another. I'm unsure about how to go about this. It doesn't really matter what size the array is but lets just say for the sake of doing it that its size 10. I am little weak with MIPS loops and am kind of confused on how to proceed.
add $s0, $zero, $zero
add $t0, $zero, $zero
lui $s0, 0x1001
ori $s0,$s0,0
lui $t0, 0x1001
ori $t0, $t0, 0x0040
There my initialization with $s0 being the address first element in the first array and $t0 being the address of the first element in the 2nd one.

I do not believe the code you have provided is correct, but assuming it is, you would do something like this:
xor $t1, $t1, $t1 ; Zero out $t1
lw $t2, array_length ; Load the length of the array in $t2
loop_start:
lb $t3, $s0 ; Load the next byte from $s0 into $t3
sb $t3, $t0 ; Store the by in $t3 into $t0
addi $s0, $s0, 1 ; Move to the next byte in the source
addi $t0, $t0, 1 ; Move to the next byte in the destination
addi $t1, $t1, 1 ; increment the counter
blt $t1, $t2, loop_start ; Jump to the start of the loop of there are more bytes
Disclaimer: I have not programmed in MIPS since college so this code may not be 100% accurate, but I believe it will give you a place to start.

Related

why i need sll to add four zeros in $t1, i dont understand the need to multiply $s3 with 2 twice using sll

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.

copy a set of continuous values from one location to another in MIPS assembly

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?

MIPS: How to access an array full of zero with loop

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

C-Code to MIPS Assembly

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

Mips, how to read array and print them?

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

Resources