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

时间:2016-05-26 03:21:13

标签: exception assembly 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?

1 个答案:

答案 0 :(得分:1)

正如大卫所说,你没有将$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时,它实际上是一个伪操作。看一下序列,您会看到sw生成lui $at,...然后生成sw $s1,0($at)

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

因此,您可以手动编写la代码。但是,[AFAIK],没有办法指定/分割&#34;上/下&#34;符号的形式与伪操作的方式有关。