数组的 MIPS 指令 sll

MIPS instruction sll for array

通过查看 t1=A[j] 的示例,试图了解如何在 MIP 中执行 t0 = A[j-1] 详情

1. j is $s2, initialized to 5  
2. i is $s1  
3. Array is $s0

我有例子 t1=A[j]

MIPS

sll $t3, $s2, 2 //I don't really understand why we need to do a left shift of 2 
add $t5, $s0, $t3 
lw , 0($t5) 

我参考了另一个 Whosebug post,其中指出

So the instruction sll $t0, $s0, 2 is multiplying $s0 by 4 (2^2) and writing back to $t0.

但我没有看到 t0 = A[j]

的任何乘法

您的 MIPS 机器中的内存可以按字节寻址,即在地址 0 处有一个字节(8 位)内存,在地址 1 处有一个内存,等等。MIPS 机器上的整个 "word" 包括四个字节(32 位)。因此,您可以将地址 0 到 3 处的字节解释为单个字。然后你也可以将地址 1 到 4、2 到 5、... 4 到 7 处的字节解释为单个单词,但除了最后一个 4..7 选项之外的所有字节都与 0..3 字节部分重叠。

所以要在内存中存储字数组(32位整数),数组的每个元素都有独立的值,不受其他元素的影响,你至少需要4*N字节的内存。

您的 A 指向数组中第一个元素的第一个字节的地址。那么 A+1、A+2 和 A+3 地址仍然指向第一个元素的后续字节。 A+4地址是第二个元素第一个字节的地址。

C语言内置了"pointer math",其中*(A+2)等表达式等同于A[2],因为C编译器会检查指针的类型,并乘以“2”乘以单个元素的大小。

但在汇编中你必须自己做,即在字节数组中 A[j] 的地址很简单 adr = A + j,但对于每个元素占用四个字节的字数组,正确的地址计算是adr = A + j*4.

由于整数二进制编码的工作方式,左移两位与将数字乘以值 4 相同。

所以sll $t3, $s2, 2实际上是t3 = j * 4,后面加上A地址,最后的值作为加载字的地址。

类似于在 MIPS 汇编中访问 A[j-1](在 C 语法中),您必须将原始内存地址计算为 adr = A + j*4 - 4(或 adr = A + (j-1)*4,以更易于实现的为准。 .实际上通常在这种循环中你不会每次都计算指针,而是保持以前的指针值,然后对它做+-4移动到next/previous 内存中的元素,没有 multiplication/shifting).