它不应该是mips的错误

时间:2017-08-18 12:19:27

标签: assembly mips

有人可以告诉我为什么我有这个错误?该错误表示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)

1 个答案:

答案 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字节对齐,底部三位必须为零。如果您的地址采用十六进制格式,则最后一位数字必须为08(二进制为00001000)。任何其他十六进制数字在最低三位设置了一些位,即这样的地址不能被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