2014-09-26 111 views
1

對於我的任務,我們給出了一個名稱數組和一個代表對應名稱(基本上是字典或地圖)的年齡的整數數組。我們應該從用戶那裏讀取一個字符串,如果這個名字在數組中,那麼我們打印這些人的年齡。繼承人是我到目前爲止有:MIPS:訪問並比較字符串數組中的元素

.data 
names: .asciiz "steve","john","chelsea","julia","ryan" 
ages: .byte 20,25,22,21,23 
out1: .asciiz "Please enter a name:" 
out2: .asciiz "Age is: " 
notfound: .asciiz "Not found!" 
input: .asciiz 

.text 
li $v0, 4 
la $a0, out1 
syscall  #prompts user for name 

li $v0, 8 
la $a0, input 
li $a1, 20 
syscall  #Reads a name into address "input" 

CheckNames: #needs to compare the input string with each element of "names" array and return 1 if they match 
la $t0, (names) 
la $t1, (input) 
beq $t1, $t0, printAge 

printAge: 

我意識到,我的CheckNames功能是錯誤的,但我不知道如何通過名稱數組迭代時每名尺寸不同(因爲我不能用一個偏移量以獲得下一個名稱)

+0

查看此答案:http://stackoverflow.com/a/26045398/583570 – markgz 2014-09-26 01:44:05

回答

1

我今天遇到了這個問題。如果它仍然可以幫助你(或任何其他人),我可以利用Assembly中的.asciiz數據這個事實來克服這個問題,它是一個特殊的字符串,它總是以一個特殊的信號終止它們:NUL。 ASCII碼的桌子下面可以幫助ilustrate這樣的:在腦海

ASCII Table

飼養每一個字符填充的8位信息(1個字節),你可以使用這些知識要經過的所有字節字符串的數組中通過比較加載字節和$ 0寄存器(或者一個數據等於零的寄存器)來識別每個世界的終點。

僞代碼介紹如下,以幫助您構建自己的代碼:

move $a1, $s0 # $s0 register store the normal index of the string names(1), for example 
li $t0, 0 
li $t2, 0 # cont to know how many word did you pass 
li $t1, maxSpace # maxSpace is that maximum space in the array 
while ($t2<$t1) { 
    branch to "final", if $t1 == $a1 
    lb $t3, names($t0) 
    branch to "isnotNUL", if $t3 != $0 
    $t2 = $t2 + 1 
    $t0 = $t0 + 1 
    isnotNUL: 
    $t0 = $t0 + 1 
} 
# normal part of code to print a string .asciiz passing the start adress to $a0 
final: 
    li $v0, 4 
    la $a0, names($t0) 
    syscall 
    jr $ra 

只是有一個問題,這個方法:迭代可能是非常慢的 - 特別是如果該數組是大和字符串也很大。如果這是你的情況,你不想這樣做,你可以修改代碼來保存數組中每個字符串的字節數,並用這些信息構造一個LUT(查找表)。所以,你可以在程序開始時運行這個函數,當打印信息的時間已經到來時,你已經知道你所關注的地址,首先加載數組的初始地址並添加保存在LUT中的數字。