我試圖接受一些接受陣列長度的用戶輸入,并且用戶能夠為該陣列的每個索引分配數字,然后將其列印出來。我基本上想做的Java代碼是:
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
int[] array = new int[N];
for (int i=0; i<N; i ) {
array[i] = sc.nextInt();
}
for (int i=0; i<N; i ) {
System.out.println(array[i]);
}
這是我目前在 MIPS 中所擁有的,但是我在訪問陣列的特定索引時遇到了問題。
.data 0x0
array:
.space 4
.text 0x3000
main:
# read in the N (number of elements)
addi $v0, $0, 5 # system call 5 is for reading an integer
syscall # integer value read is in $v0
add $s0, $0, $v0 # copy N into $s0
add $t0, $0, $0 # for (i = 0;... store i in $t0
loop:
beq $t0, $s0, printArray # go to print array if i == N
sll $t1, $t0, 2 # convert "i" to word offset by multiplying by 4
addi $v0, $0, 5 # system call 5 is for reading an integer
syscall # integer value read is in $v0
add $s1, $0, $v0 # copy input into $s1
sw $s1, array($t1) # store input at array[i], where word aligned i is in $t1
addi $t0, $t0, 1 # for (...;...; i increment i
b loop # branch to beginning of loop
printArray:
add $t0, $0, $0 # for (i = 0;... store i in $t0
add $t1, $0, $0
add $t2, $0, $0
j printArrayLoop
printArrayLoop:
beq $t0, $s0, exit # exit if i == N
addi $v0, $0, 1 # system call 1 is for printing an integer
lw $a0, array($t0) # bring the value at index $t0 in array into $a0
syscall # print the integer
# Print a newline
addi $v0, $0, 4 # system call 4 is for printing a string
la $a0, newline # address of last printed integer is in $a0
syscall # print the newline
addi $t0, $t0, 1 # for (...;...; i increment i
b printArrayLoop # jump to beginning of printArrayLoop
exit:
ori $v0, $0, 10
syscall
uj5u.com熱心網友回復:
索引需要縮放以產生位元組偏移量,然后可以與陣列的基地址一起使用。為什么?因為每個整數占用 4 個位元組,并且在記憶體中,這 4 個位元組中的每一個都有自己的地址。陣列中的下一個整數(例如 at i 1)從數字上比上一個(例如 at i)高 4 的地址開始。因此,我們按陣列元素的大小縮放索引,以產生一個位元組偏移量來訪問陣列的索引元素。
復制$v0到沒有意義$s1,它會很好地從 存盤到記憶體中$v0。
您已將回圈從 Java 中的 for 回圈更改為匯編中的 do-while,這意味著如果用戶輸入的計數為 0,它將在 Java 版本中作業,但在匯編版本中會中斷,因為它仍然會要求至少一項輸入。Java 版本將遵循以下模式:
int i = 0;
while ( i < N ) {
<for-loop-body>
i ;
}
所以,回圈測驗,回圈體,增量,回圈測驗,回圈體,增量...
通過系統呼叫,看起來您正在使用 MARS 或 QtSpim,并且默認情況下這些都沒有使用分支延遲槽。我猜您正在為此選擇選項?
將增量放入分支延遲槽的方法也會比您預期的多回圈一次:在 Java 版本中,增量將發生在回圈退出測驗之前,但在匯編版本中,在.
這是一種從偽代碼開始的非常好的方法——它通常提供相當大的清晰度,這在沒有演算法的情況下很難從頭開始用匯編撰寫。但是您應該嘗試更直接地遵循您的偽代碼,而不是在將其轉換為匯編代碼時進行任意更改。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/324827.html
