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

Assembly MIPS:使用I/O在.Data中存储和读取整数,assembly,mips,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: .

我只是在学习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是一个三角形数字

我知道问题是我读的是测试地址,而不是内容,但我很难弄清楚如何让它读测试


我正在火星上编译这个

我已经修复了下面的错误。但是,在我们讨论这一点之前,有几个风格点


我总是称赞好的评论。你的每一条指令都有明确的措辞。这是因为您刚刚开始,正在尝试理解每一条指令及其作用

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

因此,在我能够诊断和修复您的程序之前,我做的第一件事就是将注释精简一点。另外,我喜欢遵循80列规则,特别是对于asm

如果
li$v0,
行有注释,
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

    # 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

我已经修复了下面的错误。但是,在我们讨论这一点之前,有几个风格点


我总是称赞好的评论。你的每一条指令都有明确的措辞。这是因为您刚刚开始,正在尝试理解每一条指令及其作用

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

因此,在我能够诊断和修复您的程序之前,我做的第一件事就是将注释精简一点。另外,我喜欢遵循80列规则,特别是对于asm

如果
li$v0,
行有注释,
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

    # 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

您仍然可以使用
move$a0、
以及
move$t0、
。对于能够利用并行性的CPU来说,读取其结果较早产生的寄存器通常是一种良好的做法。(如果有1个周期的延迟
move
指令,则按顺序1 insn/clock流水线MIPS可能不会在意。但最简单的流水线,不转发,可以避免这样的危险。)@PeterCordes是的。我使用了
move$t0,$v0
,然后
move$a0,$t0
,假设有一些干预代码会做一些[破坏性的]事情。(例如)我会颠倒消息和值打印的系统调用顺序,得到类似于:“你的号码是:73”的内容。哦,对了,我明白了。我快速浏览了一下,认为您是在整个系统调用中保存它,而不是在系统调用之前。您仍然可以使用
move$a0、
以及
move$t0、
。对于能够利用并行性的CPU来说,读取其结果较早产生的寄存器通常是一种良好的做法。(如果有1个周期的延迟
move
指令,则按顺序1 insn/clock流水线MIPS可能不会在意。但最简单的流水线,不转发,可以避免这样的危险。)@PeterCordes是的。我使用了
move$t0,$v0
,然后
move$a0,$t0
,假设有一些干预代码会做一些[破坏性的]事情。(例如)我会颠倒消息和值打印的系统调用顺序,得到类似于:“你的号码是:73”的内容。哦,对了,我明白了。我快速浏览了一下,认为您是在整个系统调用中保存它,而不是在系统调用之前保存它。