MIPS:使用I / O在.Data中存储和读取整数

时间:2016-09-18 19:55:04

标签: assembly mips

我正在学习MIPS,我正在尝试接受用户输入,将其存储在.data中,然后输出它。这是我目前的代码。

.data
test:
.word 4 #make a 4 byte (32 bit) space in memory for a word with address insert_into
Input:
.asciiz "\Please Enter a Positive Integer: " #in unused memory store an integer
Triangular_Output:
.asciiz " is a Triangular Number."
Not_Triangular_Output:
.asciiz " is not a Triangular Number: " 
.text
main:

la $a0, Input #load address Ask_Input from memory and store it into arguement register 0
li $v0, 4 #loads the value 4 into register $v0 which is the op code for print string
syscall #reads register $v0 for op code, sees 4 and prints the string located in $a0

la $a0, test #sets $a0 to point to the space allocated for writing a word
li $v0, 5 #load op code for getting an integer from the user into register $v0
syscall #reads register $v0 for op code, sees 8 and asks user to input a string, places string in reference to $a0

la $a0, test #load address insert_into from memory and store it into arguement register 0
li $v0, 1 #loads the value 1 into register $v0 which is the op code for print integer
syscall #reads register $v0 for op code, sees 4 and prints the string located in $a0

la $a0, Triangular_Output #load address Tell_Output from memory and store it into arguement register 0
li $v0, 4 #loads the value 4 into register $v0 which is the op code for print string
syscall #reads register $v0 for op code, sees 4 and prints the string located in $a0

li $v0, 10 #loads op code into $v0 to exit program
syscall #reads $v0 and exits program

我收到了这个

请输入正整数:6

268500992是一个三角数。

我知道问题在于我正在阅读测试的地址而不是内容,但我无法弄清楚如何让它读取测试。

我正在MARS中编译这个

1 个答案:

答案 0 :(得分:1)

我已修复了下面的错误。但是,在我们达到一些风格点之前......

我总是赞扬好评。你的是每条指令的明确措辞。这是因为你刚开始并试图理解每条指令及其作用。

但是,好的评论应该表明意图(即)算法正在做什么而不仅仅是模仿指令。指令是“如何”,评论应该是“什么/为什么”。

所以,在我能够诊断并修复你的程序之前,我做的第一件事就是稍微减少评论。另外,我喜欢遵循80列规则,特别是对于asm。

如果syscall行有一个,那么

li $v0,...确实不需要评论。

如果您在记住给定指令的作用时遇到问题,请考虑顶部的注释块,该块会解释每个注释的机制。你正在重复指令集引用,但它比在每一行上做的更好

这是简化的代码,带有注释和修复的错误:

    .data

    # make a 4 byte (32 bit) space in memory for a word with address insert_into
    # in unused memory store an integer
test:       .word       4

Input:      .asciiz     "\Please Enter a Positive Integer: "

Triangular_Output:  .asciiz " is a Triangular Number."
Not_Triangular_Output:  .asciiz " is not a Triangular Number: "

    .text

main:
    la      $a0,Input               # address of string to print
    li      $v0,4                   # syscall for print string
    syscall

    # NOTE/BUG: syscall 5 does _not_ need $a0 to be preset and it returns the
    # read value in $v0
    la      $a0,test                # get address of test
    li      $v0,5                   # syscall getting an integer from the user
    syscall

    # here are two ways to save off the value:
    move    $t0,$v0                 # save to a register that won't be clobbered
    sw      $v0,test                # save to memory location

    # NOTE/BUG: we do _not_ want the _address_ of test, but rather its
    # _contents_ (i.e.) use "lw" instead of "la"
    la      $a0,test                # get address of test
    lw      $a0,test                # get value of test
    li      $v0,1                   # syscall for print integer
    syscall

    la      $a0,Triangular_Output
    li      $v0,4                   # syscall for print string
    syscall

    li      $v0,10                  # syscall for program exit
    syscall

这是编写程序的一种稍微瘦一点的方法:

   .data

    # make a 4 byte (32 bit) space in memory for a word with address insert_into
    # in unused memory store an integer
test:       .word       4

Input:      .asciiz     "\Please Enter a Positive Integer: "

Triangular_Output:  .asciiz " is a Triangular Number."
Not_Triangular_Output:  .asciiz " is not a Triangular Number: "

    .text

main:
    la      $a0,Input               # address of string to print
    li      $v0,4                   # syscall for print string
    syscall

    li      $v0,5                   # syscall getting an integer from the user
    syscall

    # NOTE: this assumes we will use the value later -- otherwise, we could
    # replace the _two_ move instructions with a single "move $a0,$v0"
    move    $t0,$v0                 # save to a register that won't be clobbered

    move    $a0,$t0                 # get value to print
    li      $v0,1                   # syscall for print integer
    syscall

    la      $a0,Triangular_Output
    li      $v0,4                   # syscall for print string
    syscall

    li      $v0,10                  # syscall for program exit
    syscall