String 在MIPS中查找给定字符串中的元音数
我必须编写一个程序来计算MIPS中字符串中的元音数。我当前的代码在QtSPim中给了我一个内存越界错误。 我在MIPS的初学者水平,所以任何帮助将不胜感激。 迄今为止的代码:String 在MIPS中查找给定字符串中的元音数,string,mips,qtspim,String,Mips,Qtspim,我必须编写一个程序来计算MIPS中字符串中的元音数。我当前的代码在QtSPim中给了我一个内存越界错误。 我在MIPS的初学者水平,所以任何帮助将不胜感激。 迄今为止的代码: .data str: .space 20 my_chars: .space 20 vow1: .byte 'a' vow2: .byte 'e' vow3: .byte 'i' vow4: .byte 'o' vow5: .byte 'u' .text main: li $s0,0
.data
str: .space 20
my_chars: .space 20
vow1: .byte 'a'
vow2: .byte 'e'
vow3: .byte 'i'
vow4: .byte 'o'
vow5: .byte 'u'
.text
main:
li $s0,0 #initilaze loop var1
li $t0,20 #initialize loop var2
li $s1,0 #initialize counter
la $t1, my_chars # base address of array
li $a1,20 #max input to be read
li $a0,8
syscall
loop:
beq $s0, $t0, exit
la $t2, str #string into t2
lb $v0, 0($t2) #access first index
lb $t9, vow1
beq $v0, $t9, then #comparing to a
then:
addi $s1, $s1, 1
lb $t8, vow2
beq $v0, $t8, then1 #comparing to e
then1:
addi $s1, $s1, 1
lb $t7, vow3
beq $v0, $t7, then2 #comparing to i
then2:
addi $s1, $s1, 1
lb $t6, vow4
beq $v0, $t6, then3 #comparing to o
then3:
addi $s1, $s1, 1
lb $t5, vow5
beq $v0, $t5, then4 #comparing to u
then4:
addi $s1, $s1, 1
addi $t1, $t1,1 #increment base address
addi $s0, $s0,1 #increment loop variable
j L1
syscall
因为您发布的代码缺少标签等。我无法运行它来查找运行时错误 从外观检查来看,从用户输入代码读取有一些问题
li$a0,8
应该是li$v0,8
[读取字符串的系统调用号]<代码>$a0应包含要读入的缓冲区地址。在您的代码中,这是8
,并且[可能]不是有效地址。因此,您可能需要类似于la$a0,my_chars
或la$a0,str
的内容。其中一个应该是输入缓冲区,另一个似乎不必要
当我尝试添加标签(基于有根据的猜测)时,我意识到如果元音在一个数组中,你的程序可能会简单得多,所以我重构了代码
我还更改了循环终止以查找EOS(0x00),而不是减少计数,这可能是另一个越界问题的潜在来源。这也减少了所需的寄存器数量(即降低了复杂性)
我添加了缺少的样板文件/系统调用[请原谅这种无缘无故的风格清理]:
.data
vowel: .asciiz "aeiou"
msg_prompt: .asciiz "Enter string: "
msg_out: .asciiz "Number of vowels is: "
msg_nl: .asciiz "\n"
str: .space 80
.text
.globl main
main:
# print user prompt
li $v0,4
la $a0,msg_prompt
syscall
# get string to scan
li $v0,8
la $a0,str
li $a1,80
syscall
li $s2,0 # initialize vowel count
la $s0,str # point to string
# registers:
# s0 -- pointer to string character
# s1 -- pointer to vowel character
# s2 -- count of vowels
#
# t0 -- current string character
# t1 -- current vowel character
string_loop:
lb $t0,0($s0) # get string char
addiu $s0,$s0,1 # point to next string char
beqz $t0,string_done # at end of string? if yes, fly
la $s1,vowel # point to vowels
vowel_loop:
lb $t1,0($s1) # get the vowel we wish to test for
beqz $t1,string_loop # any more vowels? if not, fly
addiu $s1,$s1,1 # point to next vowel
bne $t0,$t1,vowel_loop # is string char a vowel? -- if no, loop
addi $s2,$s2,1 # yes, increment vowel count
j string_loop # do next string char
string_done:
# print count message
li $v0,4
la $a0,msg_out
syscall
# print vowel count
li $v0,1
move $a0,$s2
syscall
# print a newline
li $v0,4
la $a0,msg_nl
syscall
# exit program
li $v0,10
syscall
您的问题至少应包括确切的错误消息和错误所指的代码行。它显示内存超出范围消息,而不是我所说的其他消息。您应发布准确、完整的消息,并指出错误消息所指的代码行。确切消息:突出显示的“内存地址超出边界”行:[004000b4]0000000 c syscall;50:syscallWell,在您发布的代码末尾有一条错误的
syscall
指令。这应该做什么?它前面的行是无条件跳转到代码中不存在的某个标签L1
。