将C转换为MIPS - 嵌套数组

Mit*_*aro 5 c assembly mips

我正在研究MIPS汇编语言并在本书中遇到了这个例子,对我而言似乎不正确.如果它不是我在本书中发现的第一个错误.

变量fg是分配寄存器$s0$s1分别为数组的基地址AB$s6$s7分别.

c代码示例是:

f = g - A[B[4]];
Run Code Online (Sandbox Code Playgroud)

并提供相应的MIPS程序集:

lw  $t0, 16($s7)
lw  $s0, 0($t0)
sub $s0, $s1, $s0
Run Code Online (Sandbox Code Playgroud)

根据我的理解,上面的MIPS代码将从内存中提供的一些随机数据加载$t0,然后从中减去$s1并且不访问$t0表示的数组的索引$s6.

根据我的理解,正确的MIPS组件将遵循以下方式:

lw  $t0, 4($s7)
add $t0, $t0, $s6
sll $t0, $t0, 2
lw  $s0, 0($t0)
sub $s0, $s1, $s0
Run Code Online (Sandbox Code Playgroud)

我是正确的,这是书中的错误,或者我误解了一些东西.


编辑:修正了Chris Dodd指出的修正后的mips代码中的错误

小智 5

这适用于任何人(可能是CprE 381学生),他们可能偶然发现这一点,寻找一个好例子.OP编辑的代码仍然不正确.第一个加载字函数的偏移量应为16.如果存储器宽度为32位,则可能为4,但不需要移位/乘法.假设存储器为8位宽,则需要切换加和移位功能.在OP的代码中,它将A [B [4]/4]的地址乘以4.首先移位/乘法将获得正确的索引.正确的代码是:

lw  $t0, 16($s7)   # gets the value of B[4]
                   # offset could be 4 depending on memory width
                   # but then the shift would not be needed
sll $t0, $t0, 2    # this multiplies the index by 4 to get the address offset
add $t0, $t0, $s6  # adds the base address of A and the offset
lw  $t0, 0($t0)    # loads the value at the address
sub $s0, $s1, $t0  # performs subtraction and stores in f
Run Code Online (Sandbox Code Playgroud)

如果有人对16比4的整个偏移以及是否需要转换感到困惑,那么让我解释一下.如果存储器宽度是32位,那么整个32位整数可以存储在一个存储器位置中.如果是这种情况,则数组索引与地址偏移量相同.但是,如果存储器仅为8位(1字节)宽,则在4个存储器位置(每个字节1个地址)存储32位整数.这就是您需要将索引移位2(或乘以4)以获得正确的地址偏移量的原因.


Mit*_*aro 0

正如我所指出的,书中有一个错误。自从发现这个错误以来,我发现了几个这样的错误。