我正在尝试编写一个程序,该程序接收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]没有一种方法可以像伪操作那样指定/分割符号的"上/下"。