问题
I'm working on translating the below C++ code to MIPS (this is just a small portion of the program that I'm stuck on), and I understand the gist of how to set $t
registers to take the array values given, but I'm completely stuck on
pos[count] = i;
I've tried sw
, lw
, but everytime I try these, I get address out of range exceptions/etc.
Can someone explain to me what's going wrong here? When the loop gets to pos[count] = i
, I need to change pos[count]
from 0xffffffff
to (i)
for each loop iteration. Is the error coming because I need to adjust for the -1's in pos[]
?
I'm completely lost and haven't been able to find any explanations that are similar enough to this problem.
(Apologies for the formatting, because MIPS has so many tabbed lines, the formatting for posting here is exceptionally wacky)
.data
x: .word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
pos: .word -1
.word -1
.word -1
.word -1
.word -1
.word -1
.word -1
.word -1
.word -1
.word -1
d: .word 73
.word 47
.word 23
.word 26
.word 67
.word 99
.word 13
.word 53
.word 1
.word 97
sp: .asciiz " "
endl: .asciiz "\n"
# $s0 count
# $s1 key
# $s2 i
.text
main: addi $s0, $0, 0 # int count = 0;
addi $s1, $0, 24 # int key = 24;
addi $s2, $0, 0
la $s3, d
la $s4, pos
la $s5, x
# for (int i=0; i<10; i++) {
loop: mul $t0, $s2, 4 # if (d[i] >= key) {
add $t0, $t0, $s3
lw $t0, ($t0)
blt $t0, $s1, loop1
sll $t1, $s0, 2 # $t1 = count * sizeof(int)
addu $t2, $s4, $t1 # $t2 = &pos[count];
lw $t2, ($t2) # $t2 = pos[count];
add $t3, $s5, $t1 # $t3 = &x[count];
lw $t3, ($t3) # $t3 = x[count];
sw $s2, ($t2) # pos[count] = i;
# x[count] = d[i];
loop1: addi $s2, $s2, 1 # i++;
addi $s0, $s0, 1 # count++;
# }
# }
Here's the C++ code equivalent:
#include <iostream>
using namespace std;
int x[10] = {0};
int pos[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
int d[10] = {73, 47, 23, 26, 67, 99, 13, 53, 1, 97};
int main() {
int count = 0;
int key = 24;
for (int i=0; i<10; i++) {
if (d[i] >= key) {
pos[count] = i;
x[count] = d[i];
count++;
}
}
for (int i=0; i<10; i++) {
if (pos[i] < 0)
break;
cout << pos[i] << " " << x[i] << endl;
}
}
回答1:
This part is wrong:
lw $t2, ($t2) # $t2 = pos[count];
add $t3, $s5, $t1 # $t3 = &x[count];
lw $t3, ($t3) # $t3 = x[count];
sw $s2, ($t2) # pos[count] = i;
Why are you loading pos[count]
and x[count]
when you want to write to both? Not only is this unnecessary, it will destroy $t2
and $t3
so when you really want to write, they will no longer be valid.
Also, the end of the loop is wrong, the count++
should be inside the condition. For that you will need to swap the last two lines (including the label).
A slightly cleaned up version could look like:
.data
x: .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
pos: .word -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
d: .word 73, 47, 23, 26, 67, 99, 13, 53, 1, 97
# $s0 count
# $s1 key
# $s2 i
.text
.globl main
main: addi $s0, $0, 0 # int count = 0;
addi $s1, $0, 24 # int key = 24;
addi $s2, $0, 0 # int i = 0;
# for (int i=0; i<10; i++) {
loop: sll $t0, $s2, 2 # $t0 = i * sizeof(int)
lw $t0, d($t0) # $t0 = d[i]
blt $t0, $s1, loop1 # if (d[i] < key)
sll $t1, $s0, 2 # $t1 = count * sizeof(int)
sw $s2, pos($t1) # pos[count] = i
sw $t0, x($t1) # x[count] = d[i]
addi $s0, $s0, 1 # count++;
loop1: addi $s2, $s2, 1 # i++;
blt $s2, 10, loop
回答2:
int count(int a[], int n, int x){ int res = 0; int i = 0; for(i = 0; i != n; i++) if(a[i] == x) res = res + 1; return res; }
Write a MIPS assembly program that will make use of the function count above as follows: Hard-code the following 10 values into array a: 128, 10, 23, 12, 128, 9, 220, 46, 128, 5 Hard-code n = 10 Prompt the user to enter a value as follows: “Please enter an integer value” Read the integer value and store it (lets call it x) Call the function count with the following arguments: count(a, 10, x) Output the results as follows: “The number of times x appears in the list is res times” Exit the program
来源:https://stackoverflow.com/questions/19102700/integer-arrays-in-mips-setting-arrayindex-to-iteration-value-i