2010-11-14 147 views
0

我正在研究一个将在pcspim上运行的mips程序,我需要一点帮助。该程序的描述是:编写一个程序,该程序从键盘读取一个字符串,将其存储在内存中,然后计算并打印每个字符的频率;然后它反转字符串并打印反转的字符串。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阵列。所以最后我试图打印出第一个字母。但它似乎没有打印任何东西。

有什么建议吗? 谢谢。

+0

我从来没有使用PCSPIM,但它看起来像'syscall' 4打印一个字符串,而不是一个字符。您可能想要尝试删除'lb'指令并将整个字符串移动到'$ a0'中。 (它已经存在了,但是你可以在那里做一个'移动$ a0,$ t0' – mjschultz 2010-11-14 23:03:33

+0

我已经忘记了我对MIPS汇编所知甚少,但在前几行中,你展示了什么是提示符使用la $ a0,提示。所以为什么你不显示什么在userString通过:la $ a0,userString?为什么所有其他的指令,这可能会或可能不会是正确的? – 2010-11-14 23:08:08

+0

yeaa我只是不知道我将如何能够将一个用户输入字符串存储到数组中,我在网上查了一下,并尝试了一些他们的代码,所以我不太确定,我真的很讨厌mips:( – John 2010-11-14 23:12:20

回答

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字符串的地址加载到第一个参数寄存器$a0中。最后一位只是执行将字符串放在屏幕上的系统调用。

第二部分

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

该行为jr $ra,表示“跳转到存储在寄存器$ra(返回地址)中的位置”。你可能不希望这样做,因为它标志着主函数的结束,并且可能你现在退出到命令行,可能最好将它移除。

第三部分

同样,你装的userString地址为$a0(并且也移动到$t0下一行)。现在变得很奇怪,你将userString的第一个字节0($t0)加载到$t1。这是一个ASCII字符值(如72或其他)。然后用打印字符串系统调用(#4)和参数$t1再次启动系统调用。你认为这将打印出我不同意的第一个字母。这是为什么。如果用户输入字符串“Hello,world!“这是什么样子的记忆:

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地址到寄存器$a0,然后做系统调用#4应该打印userString到屏幕上。

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 
+0

关于字符的大小,每个字符都是1字节的实体(并使用'lb'或加载字节指令),字是4字节的实体(并使用'lw'或加载字指令)。至于为什么它只显示一个字母,你认为什么值存储在's0'在分支操作?它是'userString'的地址,对吗?你认为是什么,是不是n或大于256? – mjschultz 2010-11-15 04:20:01