我正在用MIPS编写一些代码,要求用户输入一个字符串,并在Stack的帮助下从该字符串中删除元音,这是我目前所拥有的,抱歉,因为我对MIPS相当陌生,所以有点马虎
.text
.globl main
main:
li $v0, 4
la $a0, prompt # prompt user for string
syscall
li $v0, 8 # store string in str buffer
la $a0, str
li $a1, 120
syscall
li $t4, 0
li $t1, 0
addiu $sp, $sp, -4 # push a NUL byte onto the stack to signal its bottom
sw $zero, ($sp) # remember, always access the stact using words, not bytes!
loop:
lbu $t0, str($t1)
nop
nop
beqz $t0, end
nop
nop
addiu $t1, $t1, 1 #traverse through string until you reach the end of the string
j loop
end:
addiu $t1, -2 # backing up the index twice to start at the last character of string
loop2: lbu $t0, str($t1)
nop
nop
beq $t1, $t4, end2
nop
li $t5, 'a'
beq $t5, $t0, vowel # picking up all of the consonants and putting them in the stack
nop
li $t5, 'e'
beq $t5, $t0, vowel
nop
li $t5, 'i'
beq $t5, $t0, vowel
nop
li $t5, 'o'
beq $t5, $t0, vowel
nop
li $t5, 'u'
beq $t5, $t0, vowel
nop
vowel: addiu $t1, $t1, -1 # decrement index of string
addiu $sp, $sp, -4 # push
sw $t0, ($sp)
nop
j loop2
nop
nop
end2:
li $t1, 0 # index of first byte of str buffer
popl:
lw $t0, ($sp) # pop a char off the stack
addiu $sp, $sp, 4 # adjust $sp in load delay slot
beqz $t0, done # NUL byte means empty stack
nop # branch delay slot
sw $t0, str($t1) # store at string[$t1]
nop
addiu $t1, $t1, 1 # increment the index (in load delay slot)
j popl # loop
nop # branch delay slot
# print the reversed string
done: li $v0, 4 # print string service code
la $a0, str # address of string
syscall
li $v0, 10 # exit program
syscall
li $v0, 10
syscall
.data
prompt: .asciiz "enter a word"
number:
str: .space 128
我觉得我的很多问题都是关于我如何在堆栈中存储单个字符,以及在打印系统调用之前如何将它们弹出到字符缓冲区中。任何指导都将不胜感激,谢谢
1条答案
按热度按时间y1aodyip1#
我认为问题就在这里:
看到
sw $t0, str($t1)
这行了吗?应该是sb $t0,str($t1)
。因为堆栈需要始终保持字对齐,所以必须将所需的字母作为32位字存储在堆栈中。但是,字符串 * 中的每个字符 * 只占用一个字节,所以需要使用sb
将它们存储到字符串中。作为一个例子,我将展示如果使用输入字符串“BOOBOO”运行代码会发生什么。
这表示第一次通过时发生的情况:
在商店之后,我们有以下内容:
在存储之后,我们执行以下命令并再次循环:
如果您使用的是
sb $t0, str($t1)
,addiu $t1,$t1,1
就不会有问题。但是,由于您使用的是sw
,您会得到一个错误。这是因为MIPS * 中的lw
和sw
只能用于字对齐的地址,* 即它们的十六进制值以0、4、8、否则将导致对齐错误。执行addiu $t1, $t1, 1.
时,语句sw $t0, str($t1)
变为未对齐