assembly - 为什么这个 MIPS 文件不打印到日志中?
问题描述
就上下文而言,我是一名正在读第二本科的学生。我正在尝试测试 CS 课程的介绍,因为它主要是 Python,我不需要介绍性指导,但该课程包含一周的 MIPS 指导。我理解我想要理解的事物的唯一方法是查看旧的决赛。我一直在观看 YouTube 视频,试图了解一些 MIPS 基础知识。
这是我正在努力理解的一个问题。
a) 下面的 MIPS 程序打印了什么?
b) 修改程序以打印出 100 个字母“Z”。需要更改的每一行的方框中的阴影并重写下面的说明
ADDI $sp, $sp, -11 # Set up stack
ADDI $s3, $zero, 1 # Store 1 in a registrar
ADDI $t0, $zero, 90 # Set $t0 at 90 (Z)
ADDI $s2, $zero, 10 # Use to test when you reach 10
SETUP: SB $t0, 0($sp) # Next letter in $t0
ADDI $sp, $sp, 1 # Increment the stack
SUB $s2, $s2, $s3 # Decrease the counter by 1
BEQ $s2, $zero, DONE # Jump to done if $s2 == 0
J SETUP # If not, jump back to SETUP for loop
DONE: ADDI $t0, $zero, 0 # Null (0) to terminate string
SB $t0, 0($sp) # Add null to stack
ADDI $sp, $sp, -11 # Set up stack to print
ADDI $v0, $zero, 4 # 4 is for print string
ADDI $a0, $sp, 0 # Set $a0 to stack pointer for printing
syscall # Print to the log
我试图在两个模拟器中运行它,答案似乎是“什么都没有打印”。我想这是教授想要的答案是可以想象的,但在这个决赛的其他地方几乎没有错误,所以我对此没有信心。我猜 90 是 'Z' 的 ascii 代码,这里的想法是 'Z' 将被打印 10 次。但是要打印 10 次“Z”实际上会发生什么呢?在我一直在观看的视频中,总是有一对li
/la
一对打印说明。或者这是对的,模拟器有问题吗?
说
ADDI $sp, $sp, -11
-> ADDI $sp, $sp, -101
、
ADDI $s2, $zero, 10
->ADDI $s2, $zero, 100
和
ADDI $sp, $sp, -11
->是否正确ADDI $sp, $sp, -101
?
解决方案
有一个错误。
首先,堆栈指针减 11,然后加 10(一次一个),然后再减 11。不平衡,它不会返回到它被赋予增量和第二个减量的位置。
因此,$sp
它指向写入第一个 Z 之前的空字节——一个空字符串。
您可以通过查看第一个使用的地址来确认这一点SB
,然后查看$a0
通过系统调用#4 打印时使用的地址。
就编程风格而言,在 MIPS 上,我们通常不会弹出堆栈并假设我们的旧数据仍然存在,如果我们重新减少堆栈指针 - 虽然这将在模拟器上工作,但其他一些系统不会当您第二次递减堆栈指针时,保证您现在位于堆栈指针下方的旧数据会返回(它与中断和信号的处理方式有关)。
更好的方法是在第一次递减后将堆栈指针保留在原处,然后将堆栈指针复制到另一个寄存器以用于循环中的字节写入,而不是堆栈指针。
推荐阅读
- r - R的sum()函数中的条件语句
- vue.js - Pusher ChatKit - 房间和房间订阅 - 如何检测新消息
- javascript - 如何将 JSON 文件从 Android 上传到 Firebase 存储?
- asp.net - ASP.NET 2.0 win10无法编译调试?
- javascript - 单击时加载 HMTL5 音频(不是之前,以提高页面速度)
- php - 在 php codeigniter 中使用查询字符串时从 url 中删除 ?variable_name=
- c++ - openGL中的多个计时器
- javascript - 使用 map、filter、reduce 从数组转换为更深的树
- django - 是否可以在没有后端的情况下获得 twitter access_token?
- php - Ajax Request status as Canceled