MIPS 汇编 - 将用户输入存储到堆栈中

MIPS Assembly - Storing user input into a stack

我正在尝试将用户输入存储到堆栈中,当用户输入 0 时,程序将停止接收输入并打印出用户添加的所有数字,不包括零。我不确定如何正确地处理这个问题。到目前为止,这是我的代码。

.data
prompt: .ascii "Please enter numbers, enter (0) to exit: "

.text

main:
li $v0, 4
la $a0, prompt
syscall


do:
li $v0, 5
syscall
addi $sp, $sp, -4 # Move stack four bytes down -- MAYBE MAKE SOME OF COUNTER TO KEEP TRACK OF HOW MUCH DATA NEEDS TO BE STORED IN STACK??
sw $v0, 0($sp) # Places contents of $t0 into first spot into the stack -- THINK I NEED TO CHANGE THIS TO ACCOMADATE CHANGE IN MEMORY??
#while
bne $t0, 0, do # Branch to print section if input = 0

print:
lw $t0, 0($sp)
addi $sp, $sp, 4
# Do printing instructions here from stack

end:
li $v0, 10
syscall

非常感谢任何建议或帮助!

这应该可以作为 "unclear what you're asking" 关闭(你的问题不适合 Whosebug 这类问题......说得好),但我个人对这些广泛的风格没有问题有偏见的问题,只是答案对其他人没有太大用处,所以最好至少努力为自己利用它。

...
li $v0, 5

do:

此处 v0 中的内容是什么(即从 MARS 请求的服务)?五?在第二次循环迭代时?

syscall
move $t0, $v0 # Places input in $t0

为什么? (*)

addi $sp, $sp, -4 # Move stack four bytes down MAYBE MAKE SOME OF COUNTER TO KEEP TRACK OF HOW MUCH DATA NEEDS TO BE STORED IN STACK??

您新编辑的评论解决了最大的不足。是的,你是在盲目地从 sp 中减去而没有任何办法在以后恢复它。保持计数器是一种可能的方法,另一种是将原始 sp 存储在某个地方($sX 寄存器很方便),然后 stored_bytes = original_sp - sp;(和 count = stored_bytes>>2;,但你甚至可能不需要直接计数,如果你只想打印回值,那么使用 original_sp 值就足够了)。

sw $t0, 0($sp) # Places contents of $t0 into first spot into the stack -- THINK I NEED TO CHANGE THIS TO ACCOMADATE CHANGE IN MEMORY??

是的,它将 t0 中的值存储到地址 sp 的内存中。我不确定你编辑的评论是什么意思,你在担心什么。

while:

未使用的标签,不如把它变成评论,因为你不需要它。

beq $t0, $zero, print # Branch to print section if input = 0
j do

这大概可以变成branch-when-not-zero(bne是MIPS指令IIRC?),那么你就不需要j任何地方,当print:代码会关注

(很多更高级的 tip/info,请随意跳过)还要确保您的 MARS 模拟器在选项中延迟分支关闭(默认情况下,使 MIPS 的模拟不真实,但更容易理解和学习编码)。在真正的 MIPS CPU 上,您必须将分支代码 1 指令放在分支实际有效的位置之前(或者通过在每个分支之后使用 nop 来避免这种情况,这在极少数情况下是有效的解决方案,而且很蹩脚在其他人中)。

print:

# Do printing instructions here from stack

那么,试试吧。

您还应该在调试器中尝试您的代码,使用 single-step 指令,观察寄存器和内存内容,以更好地掌握 CPU 的工作原理。

* - 我最大的个人心理 "break-through" 当我还是个孩子的时候学习编程(基本上我在汇编中学习编程,之前做了一些 BASIC,但很早就切换到汇编,因为我想要那个 3.5MHz Z80 CPU(那个速度不是错字))的所有性能是,当我终于意识到一旦你有足够干净的计算理论公式,你可以简单地写它 1:1成计算机指令。无需手忙脚乱地添加额外的代码,使其看起来与其他东西相似等等。您所需要的只是非常清晰和深刻的理解,您真正想要计算的是什么。

在您的情况下,您希望将输入的值存储到堆栈内存中。 v0中输入的值was/is。为什么要涉及额外的 t0 寄存器?直接存储sw $v0, 0($sp)(当然是spaddi调整后)。

您的其余代码和工作可能也是如此。拿纸和笔,先试着写下你真正想要达到的目标。缺少的 counter/sp-restoration 会变得很明显,一旦您尝试创建打印代码(您会注意到打印的基端没有价值)。

请记住,数周的编码时间可以节省数小时的计划时间。