通过查看t0 = A[j-1]
的示例来尝试了解如何在MIP中执行t1=A[j]
详细信息
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 $1, 0($t5)
我引用了另一篇说明该问题的文章
因此,指令sll $ t0,$ s0、2将$ s0乘以4(2 ^ 2),然后 写回$ t0。
但是我看不到t0 = A[j]
的任何乘法
答案 0 :(得分:1)
您的MIPS机器中的内存可以按字节寻址,即地址0处有一个字节(8位),地址1处有一个,依此类推。MIPS机器上的整个“字”由四个字节(32个)组成位)。因此,您可以将地址0到3的字节解释为单个字。然后,您还可以将地址1到4、2到5,... 4到7的字节解释为单个字,但是除最后一个4..7选项外的所有字节都与0..3字节部分重叠。 / p>
因此,要将单词数组(32位整数)存储在内存中,其中数组的每个元素具有独立的值,不受其他元素的影响,则至少需要4 * N字节的内存。
您的A
指向数组中第一个元素的第一个字节的地址。那么A + 1,A + 2和A + 3地址仍然指向第一个元素的后续字节。 A + 4地址是第二个元素的第一个字节的地址。
C语言具有内置的“指针数学”,其中*(A+2)
之类的表达式与A[2]
相同,因为C编译器将检查指针的类型,并将“ 2”相乘按单个元素的大小。
但是在汇编中,您必须自己进行操作,即在字节数组中,A[j]
的地址很简单adr = A + j
,但是对于每个元素占用四个字节的字数组,正确的地址计算为{{ 1}}。
由于整数的二进制编码是如何工作的,所以左移两位是等同于将数字乘以值4。
因此adr = A + j*4
实际上是sll $t3, $s2, 2
,后来被添加到t3 = j * 4
地址中,并且最终值用作从中加载单词的地址。
类似地,在MIPS程序集中访问A
(使用C语法),您必须将原始内存地址计算为A[j-1]
(或adr = A + j*4 - 4
,以更易于实现的方式...实际上通常在这种循环中,您并非每次都计算指针,而是保留前一个指针值,并对它执行+ -4即可移动到内存中的下一个/上一个元素,而无需乘法/ shifting)。