MIPS:访问和比较字符串数组中的元素

时间:2014-09-26 01:02:39

标签: arrays 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功能是错误的,但是当每个名称的大小不同时,我不知道如何遍历名称数组(因为我不能使用偏移来到下一个名称)名)

1 个答案:

答案 0 :(得分:1)

我今天遇到了这个问题。如果它仍然可以帮助你(或其他任何人),我使用以下事实克服了这个问题:汇编中的.asciiz数据是一个特殊的字符串,它们总是以一个特殊信号终止它们:NUL。下面的ASCII表可能有助于说明这一点:

enter image description here

请记住每个字符填充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上的数字来开始的地址。 。