有人可以告诉我为什么我有这个错误?该错误表示sdc1处的未对齐地址。这对我来说似乎很好。它可以来自代码的其余部分吗?
la $a1, A
#Ask for A(1,1)
li $v0 , 4
la $a0 , a11
syscall
#Read double
li $v0 , 7
syscall
#Store double
sdc1 $f0 , ($a1)
答案 0 :(得分:0)
我不是MIPS专家,但IIRC,有两件事可以帮到你:
1)
a0-a3
是"论证"寄存器,可以根据调用约定通过子调用进行修改,您不希望存储一些指针值,您将在更长的时间内使用它。
因为寄存器s0-s7
更好,因为它们应该被任何例程保留,例如你自己的代码应该首先将它们存储在堆栈中(并在返回之前将它们恢复为原始值),然后再修改它保留A1
地址,但任何syscall
或任何正确编写的子例程都应保留s?
值。
如果您有一段不会调用任何内容的代码,您可以使用t0-t7
个寄存器作为临时值,您可以自由修改(甚至a0-a3
,因为子程序可能会修改参数值)。
2)
sdc1
指令需要将地址对齐为8字节(最低三位为零)。
如果你已经从堆中动态分配了内存,不确定它的对齐方式,则多分配+8个字节,并调整分配内存的指针((ptr+7)&(-8))
,这将清除最低的三位(也是保持原始指针值,因为您可能需要它来释放该内存)。然后使用对齐的值作为double
值的缓冲区的开头。
只是为了确保你理解" alignment"的含义。计算机地址是"对齐"通过2/4/8 / ...字节,如果它的值可以除以该数而没有余数。因此地址800是8字节对齐(800/8 = 100),但804不是8字节对齐(804/8 = 100.5)。由于通常在计算机中需要对准2的幂,并且值是以比特二进制编码的,因此不需要进行实际的值划分来验证它的对齐。使用二进制编码,清除的最低位的数量定义了它的2的幂对齐。没有清除位=奇数(仅由1对齐),最低位清除=偶数(由2对齐),两位清除=可被4整除=对齐4.因此,对于8字节对齐,底部三位必须为零。如果您的地址采用十六进制格式,则最后一位数字必须为0
或8
(二进制为0000
或1000
)。任何其他十六进制数字在最低三位设置了一些位,即这样的地址不能被8整除,因此它没有与sdc1
指令正确对齐。
因此,如果您理解上面的段落,您可以非常快速地检查某个地址在调试器中是否有效,只需通过以十六进制格式查看寄存器中的值(几乎每个调试器默认显示十六进制值,因为它使它成为人类很容易看到特定的位和字节,在十进制格式中你必须计算除以8的余数才能确定。
如何以对齐的方式定义A
数组...因为您没有说明如何定义它,所以很难说清楚。让我们猜测你使用MARS / SPIM MIPS模拟器之一进行这些练习。然后,您可以通过以下代码分配800字节对齐到8字节边界:
.align 3 # align next data item to 2^3 (= 8) boundary
array: .space 800 # allocate 800 bytes of space