我有一个家庭作业问题:
假设变量f
、g
、h
、i
和j
分配给寄存器 $s0
、$s1
、$s2
、$s3
和 $s4
,分别。假设数组A
和B
的基地址分别在寄存器$s6
和$s7
中。
B[8] = A[i–j];
对于上面的C语句,对应的MIPS汇编代码是什么?
答案是:
SUB $t0, $s3, $s4
SLL $t0, $t0, 2
ADD $t0, $t0, $s6
lw $t1, 0($t0) # A[i - j] in is $t1
和
ADDI $t0, $zero, 8
SLL $t0, $t0, 2
ADD $t0, $t0, $s7
SW $t1, 0($t0) # $t1 is Stored in B[8]
我的问题是,为什么还要费心处理第二个代码块中的前 3 行?如果您知道 $t1
将存储在 array B
的第八个元素中,那么唯一需要的指令就是 SW $t1, 32($s7)
。如果我没记错的话,这相当于第二个代码块。
最佳答案
我想答案是即使两个代码片段产生相同的结果,即
ADDI $t0, $zero, 8
SLL $t0, $t0, 2
ADD $t0, $t0, $s7
SW $t1, 0($t0) # $t1 is Stored in B[8]
和
SW $t1, 32($s7) # $t1 is Stored in B[8]
第一个消耗更多的 CPU 周期。
任何简单的编译器都能够发出第一段代码,因为它是高级语句 B[8] = result_of_calculation
的直接翻译。
第二 block 代码需要一点静态分析(即编译器必须考虑到 $s7
保存数组 B 的基地址,并且还要考虑到您将寻址这种数组的八个位置。
我的猜测是任何现代编译器都会执行最少的静态分析,因此会发出第二条指令而不是第一段代码。
关于c - 使用 MIPS 指令集时,为什么使用逻辑左移比使用加载/存储字中的偏移量更有益?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28598869/