MIPS(裸模式)字符串不会打印
MIPS (Bare Mode) String Won't Print
最近在大学开始学习 MIPS 时,我在尝试打印 1 个字符串,接受用户输入,然后打印另一个字符串并接受用户输入时遇到了一个问题。两个用户输入都应分别存储到寄存器 a0 和 a1。
每个字符串的名称是 promptD 用于 Dividend 输入,enterD 用于 Divisor 输入(您可能会猜到这是一个无符号除法计算器程序)。
在我的调试尝试中,我已将问题缩小到下面发布的一小段代码。
我认为我错误地偏移了我的第一个 .data 寄存器以到达我的第二个 .data 寄存器。我在尝试 QTspim、xspim、PCspim 和 MARS 时注意到的问题是,所有这 4 个都为 .data 中的第一个字符串提供了不同的初始寄存器地址。
例如:字符串 "Enter Dividend" 在 MARS 中将位于注册地址 0x10010000,但在 PCspim 中将从 0x10000000 开始。 "Enter Divisor" 的以下寄存器地址将在 MARS 中的 0x10010011 或 PCspim 中的 0x10000010 中。
在 MARS 的当前状态下,下面的程序片段要求用户输入股息,并将存储该值。存储到 a0 后,代码将立即失败,因为第 37 行(这只是第 3 个系统调用)运行时异常位于 0x00400024:地址超出范围 0x00000004。它根本没有提示 "Enter Divisor"。
为了真正看到问题的实际情况,我认为 运行 MARS 中的这一点有助于使其更加清晰。这是一个抵消问题吗?我是否在没有看到它的情况下破坏了寄存器?我在这里没有找到很多 MIPS 帮助来处理没有伪指令的问题。我意识到他们,我可以直接加载一个地址 (la)...但我不能在这里使用它们。
谢谢
.globl main
.data #for the data
promptD: .asciiz "Enter Dividend \n"
enterD: .asciiz "Enter Divisor \n"
# result: .asciiz "Result = "
.text #for the instructions
main:
#for Dividend
addi $v0, [=10=], 4 #store string instr to v0
lui $a0, 0x1001 #address of promptD
syscall #display promptD
addi $v0, [=10=], 5 #store input instr to v0
syscall # Get dividend
add $a0, [=10=], $v0 # Dividend to $a0
#for Divisor
addi $v0, [=10=], 4 #store string instr to v0
lui $a1, 0x1001 #Where I think the problem is...
#Address of first string followed by add offset?
addi $a1, $a1, 33 #Maybe incorrect offset?
syscall #display enterD
addi $v0, [=10=], 5 #store input instr to v0
syscall # Get divisor
add $a1, [=10=], $v0 # Divisor to $a1
#end snippet
这是有问题的代码:
lui $a1, 0x1001 #Where I think the problem is...
#Address of first string followed by add offset?
addi $a1, $a1, 33 #Maybe incorrect offset?
- 您使用了错误的寄存器。系统调用 4 的参数应该放在
$a0
,而不是 $a1
.
- 偏移量 33 不正确。如果您查看 Mars 中的数据段查看器,您可以看到
promptD
的 NUL 终止符字节位于 0x10010010,而 enterD
字符串从 0x10010011 开始(如果您难以阅读十六进制 ASCII 代码,您可以勾选数据段查看器中的 "ASCII" 复选框以将数据作为字符查看)。所以你应该使用的偏移量是 0x11(十进制 17)。
最近在大学开始学习 MIPS 时,我在尝试打印 1 个字符串,接受用户输入,然后打印另一个字符串并接受用户输入时遇到了一个问题。两个用户输入都应分别存储到寄存器 a0 和 a1。
每个字符串的名称是 promptD 用于 Dividend 输入,enterD 用于 Divisor 输入(您可能会猜到这是一个无符号除法计算器程序)。
在我的调试尝试中,我已将问题缩小到下面发布的一小段代码。
我认为我错误地偏移了我的第一个 .data 寄存器以到达我的第二个 .data 寄存器。我在尝试 QTspim、xspim、PCspim 和 MARS 时注意到的问题是,所有这 4 个都为 .data 中的第一个字符串提供了不同的初始寄存器地址。
例如:字符串 "Enter Dividend" 在 MARS 中将位于注册地址 0x10010000,但在 PCspim 中将从 0x10000000 开始。 "Enter Divisor" 的以下寄存器地址将在 MARS 中的 0x10010011 或 PCspim 中的 0x10000010 中。
在 MARS 的当前状态下,下面的程序片段要求用户输入股息,并将存储该值。存储到 a0 后,代码将立即失败,因为第 37 行(这只是第 3 个系统调用)运行时异常位于 0x00400024:地址超出范围 0x00000004。它根本没有提示 "Enter Divisor"。
为了真正看到问题的实际情况,我认为 运行 MARS 中的这一点有助于使其更加清晰。这是一个抵消问题吗?我是否在没有看到它的情况下破坏了寄存器?我在这里没有找到很多 MIPS 帮助来处理没有伪指令的问题。我意识到他们,我可以直接加载一个地址 (la)...但我不能在这里使用它们。
谢谢
.globl main
.data #for the data
promptD: .asciiz "Enter Dividend \n"
enterD: .asciiz "Enter Divisor \n"
# result: .asciiz "Result = "
.text #for the instructions
main:
#for Dividend
addi $v0, [=10=], 4 #store string instr to v0
lui $a0, 0x1001 #address of promptD
syscall #display promptD
addi $v0, [=10=], 5 #store input instr to v0
syscall # Get dividend
add $a0, [=10=], $v0 # Dividend to $a0
#for Divisor
addi $v0, [=10=], 4 #store string instr to v0
lui $a1, 0x1001 #Where I think the problem is...
#Address of first string followed by add offset?
addi $a1, $a1, 33 #Maybe incorrect offset?
syscall #display enterD
addi $v0, [=10=], 5 #store input instr to v0
syscall # Get divisor
add $a1, [=10=], $v0 # Divisor to $a1
#end snippet
这是有问题的代码:
lui $a1, 0x1001 #Where I think the problem is...
#Address of first string followed by add offset?
addi $a1, $a1, 33 #Maybe incorrect offset?
- 您使用了错误的寄存器。系统调用 4 的参数应该放在
$a0
,而不是$a1
. - 偏移量 33 不正确。如果您查看 Mars 中的数据段查看器,您可以看到
promptD
的 NUL 终止符字节位于 0x10010010,而enterD
字符串从 0x10010011 开始(如果您难以阅读十六进制 ASCII 代码,您可以勾选数据段查看器中的 "ASCII" 复选框以将数据作为字符查看)。所以你应该使用的偏移量是 0x11(十进制 17)。