需要帮助MIPS计划

时间:2010-11-14 22:52:28

标签: mips

我正在研究将在pcspim上运行的mips程序,我需要一点帮助。该程序的描述是:编写一个程序,读取一个字符串(从键盘),将其存储在内存中,并计算和打印每个字符的频率;然后它反转字符串并打印反转的字符串。

到目前为止,我有......

    .data   # Data declaration section
userString: .space 256
Prompt:     .asciiz "\nEnter a word: "
newLine:    .asciiz "\n"
    .text


main:       # Start of code section
li $v0, 4
la $a0, Prompt
syscall

li $v0, 8
la $a0, userString
li $a1, 256
    syscall
jr $ra

la $a0, userString
move $t0, $a0


lb $t1, 0($t0) 
li $v0, 4
move $a0, $t1
syscall     # prints first letter of word

现在我只是想看看我是否真的将输入存储到userString数组中。所以最后我试着打印出第一个字母。但它似乎没有打印任何东西。

有什么建议吗? 感谢。

2 个答案:

答案 0 :(得分:1)

我已将代码分为三部分:提示,输入,显示。我假设前两部分是给你的,第三部分是你现在关注的。我将解释第一部分正在做什么然后解释第三部分现在正在做什么,以及你可能希望它在这一点上做什么。

    .data   # Data declaration section
userString: .space 256
Prompt:     .asciiz "\nEnter a word: "
newLine:    .asciiz "\n"
    .text

# Part I
main:       # Start of code section
li $v0, 4
la $a0, Prompt
syscall

# Part II
li $v0, 8
la $a0, userString
li $a1, 256
    syscall
jr $ra

# Part III
la $a0, userString
move $t0, $a0
lb $t1, 0($t0) 
li $v0, 4
move $a0, $t1
syscall     # prints first letter of word

第一部分

这非常简单,当我们开始执行程序计数器时,将设置为main标签的地址。它将值4加载到$v0(似乎是打印字符串系统调用号),然后将Prompt字符串的地址加载到第一个参数寄存器{{1}中}。最后一位只执行将字符串放在屏幕上的系统调用。

第二部分

现在屏幕上已经打印了$a0字符串,我们想要实际读取用户输入的内容。看起来我们正在使用系统调用#8(可能是读取字符串),因此我们将该值加载到"Enter a word: "以准备$v0。然后,因为我们想要将用户字符串读入syscall,我们将该标签的地址加载到userString(读取字符串函数的第一个参数)然后,因为我们是精明的程序员,我们给出$a0userString可以容纳多少字节(256)的上限。然后我们执行系统调用,在键盘上键入一个字符串并按Enter键,然后返回到下一行代码。

该行为$a1,表示“跳转到存储在寄存器jr $ra中的位置(返回地址)”。您可能不希望这样,因为它标记了主函数的结束,并且您可能在此时将程序退出到命令行,可能最好将其删除。

第III部分

同样,您正在将$ra的地址加载到userString(并在下一行中将其移至$a0)。现在它变得很奇怪,你将$t0的第一个字节0($t0)加载到userString。这是一个ASCII字符值(如72或其他)。然后使用打印字符串系统调用(#4)和$t1的参数再次启动系统调用。您认为会打印出该单词的第一个字母,我不同意这一点。这就是原因。如果用户键入字符串,“Hello,world!”这就是它在内存中的样子:

$t1

因此,加载userString: H e l l o , w o r l d ! offset: 0 1 2 3 4 5 6 7 8 9 10 11 12 会将字母0($t0)移动到注册表H中,然后当您执行系统调用时,它会尝试将从$t1开始的字符串打印到屏幕。但是,没有从字母H开始的字符串,它从H的地址开始。因此,如果您只是将userString的地址移到注册表userString中,那么请执行系统调用#4,它应该将$a0打印到屏幕上。

答案 1 :(得分:0)

@mjshultz

我已经改变了一点。不认为我需要2个循环。此外,我将它增加四,因为我认为每个字符是4个字节,所以要转到下一个字母,我需要将偏移量增加四个。

        .data   # Data declaration section
userString: .space 256
Prompt:     .asciiz "\nEnter a word: "
newSpace:   .asciiz " " 
newLine:    .asciiz "\n"

    .text


main:       # Start of code section
li $v0, 4
la $a0, Prompt
syscall


la $a0, userString
li $a1, 256
li $v0, 8
    syscall

la $a0, userString
move $s0, $a0

loop:   
lb $t1, 0($s0)
li $v0, 1
move $a0, $t1
syscall 

li $v0, 4
la $a0, newSpace
syscall 
addi $s0, $s0, 4

blt $s0, 256, loop