Reputation: 767
I know there is a similar question here. I'd like to think of it as a continuation of that question but more thorough.
Here is the relevant pieces of a C code which I want to translate to MIPS:
int a = [100];
...
j = 0;
while (j<50){
if (a[j] > a[99-j]) {
tmp = a[99-j];
a[99-j] = a[j];
a[j] = tmp;
}
j = j+1;
}
(So it's basically works like reverse)
So far I have done in MIPS:
.data
array: .word 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80,
79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60,
59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40,
39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20,
19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,0
.text
.globl main
main:
la $s1, array # $s1 = array address
la $s3, array
li $s0, 0 # j = 0
lw $t0, 0($s1) # $t0 = a[0]
lw $t1, 396($s3) # $t1 = a[99]
while: beq $s0, 50, end # break from while loop once j = 50
if: blt $t0, $t1, iterj # if the if statement not satisfied, branch to iterj
sw $t1, 0($s1) # write to a[99-j]
sw $t0, 396($s1) # write to a[j]
iterj: addi $s0, $s0, 1 # increment j
addi $s1, $s1, 4 # increment source address starting with j = 0
addi $s3, $s3, -4 # decrement source address starting with j = 99
lw $t0, 0($s1)
lw $t1, 396($s3)
j while
end:
Summary of what I did in MIPS:
Basically, I tried to initialise the array in $s1 and tried my best to make swaps on it. Then I realised that I also need to increment the source address at a[0] and at the same time decrement the source address at a[99]. So I was thinking I can't use just 1 array, which I then made an identical array in $s3 to handle it:
addi $s1, $s1, 4 # increment source address starting with j = 0
addi $s3, $s3, -4 # decrement source address starting with j = 99
Now is the part I need help:
The code works (swapping correctly) sequentially from 0 to 31 (all in hex form shown in MARS) then 31 to 1 then suddenly 63 to 47. There's obviously something I'm doing wrong. All I just need it to do is return 0 to 63 (in hex) or 0 to 99 (in dec) via swapping. Any hints?
Upvotes: 3
Views: 18081
Reputation: 4961
Well, you're wrong about requiring two arrays, however it is that you came to such a conclusion. Remember that anything that can be written in C can certainly be written in assembly, so the C code you provided should serve as a model.
---EDIT
What I would suggest first is load the address of the array, and calculate the end address.
la $t0 array
addi $t1 $t0 396 #last element of array
Then in the body of the loop:
lw $t2 0($t0)
lw $t3 0($t1)
sw $t2 0($t1)
sw $t3 0($t0)
addi $t0 $t0 4
addi $t1 $t1 -4
blt $t0 $t1 loop
Upvotes: 2