我正在研究MIPS汇编语言并在本书中遇到了这个例子,对我而言似乎不正确.如果它不是我在本书中发现的第一个错误.
变量f和g是分配寄存器$s0和$s1分别为数组的基地址A和B是$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)以获得正确的地址偏移量的原因.