这是一个非常好的问题,我自己找到了一个可能的解决方案。上面的答案不是无条件的。
实际上,应该可以说您希望数据段位于何处(例如,SPIM 允许您这样做)。 .data 指令采用一个可选参数,即该数据段应位于的 32 位地址。以这种方式编写异常处理程序(仅使用.kdata 而不是.data)。
一个例子:
.data 0x10001000 #remember this location
.align 0
.asciiz "MIPS IS GREAT!" #this is at offset 0
.text
.align 2
.globl main
main: #let's assume we've got no arguments
addiu $sp, $sp, -24 #subroutine prolog
sw $ra, 16($sp)
sw $fp, 10($sp)
addiu $fp, $sp, 20
ori $v0, $0, 4
lui $a0, 0x1000 #sole argument must be str pointer
ori $a0, $a0, 0x1000
syscall #print STR out on console
lw $ra, 16($sp) #subroutine epilog
lw $fp, 10($sp)
addiu $sp, $sp, 24
jal
我实际上不确定这是否是最好的解决方案,但它是我能想到的唯一解决方案(即使不使用虚拟寻址模式,即加载或存储指令的标签)并且这个想法应该可行(无论我的代码示例有效,我不知道,我没有测试过)。
编辑:
我刚刚玩过,发现了一个非常棒的技巧,它允许我们在没有任何伪指令和自然寻址模式的情况下将标签加载到寄存器中。我的例子:
.data 0x10001000
.word LABEL
LABEL: .asciiz "Get LABEL to print this C string."
.text
.align 2
.globl main
#test if it loads LABEL
main:
lui $4, 0x1000
ori $4, $4, 0x1000
lw $4, 0($4)
ori $2, $0, 4
syscall
在 SPIM 中它组装得很好!查看 0x10001000 处的内存显示,0x10001004 被存储!这种方法在内存中创建一个指针。我建议将指针放在其他可变长度数据的前面,以便您可以轻松计算指针的偏移量。