尝试在数据段中存储寄存器值时,MIPS中出现运行时异常



我正在尝试编写一个程序,该程序接收2个输入并将它们存储在寄存器中,然后将这些寄存器存储在数据段中。

.data
val1: .word 1
val2: .word 2
val3: .word 3
.asciiz "Branden"
.asciiz "Enter a number "
.asciiz "n"
.globl main
.text
main:
addi $s0, $0, 23 # initializes the register $s0 to 23
lui $a0, 0x1001
ori $a0, $a0, 20 #outputs string that is at 20
ori $v0, $0, 4 #command for output
syscall
addi $v0, $0, 5 # asks for input
syscall 
addi $s1, $v0, 0 # set the value of $s1 as the given input

lui $a0, 0x1001 
ori $a0, $a0, 20 #outputs string that is at 20
ori $v0, $0, 4 #command for output 
syscall
addi $v0, $0, 5 #asks for input
syscall
addi $s2, $v0, 0 # set the value of $s2 as the given input
sw $s1, 0($t0) # store the value of $s1 into data segment val1
sw $s2, 4($t0) # store the value of $s2 into data segment val2

ori $v0, $0, 10 
syscall

问题是我得到了这个错误:C:\Users\Danny \MIPS\assignment1.asm行34中的错误:0x0040003c处的运行时异常:地址超出范围0x00000000

错误发生在线路sw$s1,0($t0)上,但原因是什么?是否需要与sw关联的lw?

正如David所提到的,您没有将$t0设置为任何值,因此sw为零

但是,即使您想使用构造,您将如何获得地址?la使这变得容易。

我已经修复了这个错误,并重新编码使用了一些让生活更轻松的伪操作[请原谅免费的风格清理]:

.data
val1:       .word       1
val2:       .word       2
val3:       .word       3
me:     .asciiz     "Branden"
enter:  .asciiz     "Enter a number "
nl:     .asciiz     "n"
.globl  main
.text
main:
li      $s0,23                  # initializes the register $s0 to 23
la      $a0,enter               # address of string to output
li      $v0,4                   # print string syscall number
syscall
li      $v0,5                   # asks for input
syscall
move    $s1,$v0                 # set the value of $s1 as the given input
la      $a0,enter               # address of string to output
li      $v0,4                   # print string syscall number
syscall
li      $v0,5                   # asks for input
syscall
move    $s2,$v0                 # set the value of $s2 as the given input
sw      $s1,val1                # store the value of $s1 into val1
sw      $s2,val2                # store the value of $s2 into val2
li      $v0,10
syscall
# NOTE: these are alternate ways to do the stores (they're after the exit
# so they won't be executed)
la      $t0,val1                # address of val1
sw      $s1,0($t0)              # store the value of $s1 into val1
la      $t0,val2                # address of val2
sw      $s2,0($t0)              # store the value of $s1 into val2

更新:

我不允许使用la或li,但我不知道我可以直接使用val1和sw,所以这很有帮助,谢谢!

我这样做是为了显示一个表单。

但是,当以这种方式使用sw时,它实际上是一个伪-op。看看这个序列,你会发现sw生成lui $at,...,然后生成sw $s1,0($at)

伪操作的问题是,它们做一些基本指令做不到的事情。松散地[使用一些类似C的语法],la $t0,val1生成lui $at,(&val1 >> 16),然后生成ori $at,$at,(&val1 & 0xFFFF)

因此,您可以手动对la进行编码。但是,[AFAIK]没有一种方法可以像伪操作那样指定/分割符号的"上/下"。

最新更新