我正在讀一些關于將C語句翻譯成MIPS的MIPS注釋。
交換函數的C代碼如下:
swap ( int v[], int k) {
int temp;
temp = v[k];
v[k] = v[k + 1];
v[k + 1] = temp;
}
我被告知k映射到5美元,v[]的基址映射到4美元,temp映射到15美元。swap函數接受參數k=3,并假設v的基址是2000。
簡化的MIPS版本如下:
swap:
sll $2, $5, 2
add $2, $4, $2
lw $15, 0($2)
lw $16, 4($2)
sw $16, 0($2)
sw $15, 4($2)
這里的困惑是為什么在翻譯的MIPS中有sll和add?
這來自于字節可尋址,就像大多數現代機器一樣。
字節尋址意味著處理器可以訪問內存的每個字節—在這樣的系統中,將有效字節地址值增加1意味著引用內存的下一個連續字節。
int
數據類型使用的字是32-bits寬的,因此需要4字節的內存。因此,a[0]
占用字節addr+0
、addr+1
、addr+2
和addr+3
,其中addr
是a
的字節地址。a[1]
是從a[0]
偏移4字節,在addr+4
!C知道“arrays of
int
”的元素需要4個字節,每個字節之間有4個字節的間隔,因此它知道a+i
在hood下意味著a + i * 4
,它將引用數組中每個元素的4個連續地址,從i*4
開始,這為所有較低的元素留出了空間。計算
i * 4
有時被稱為“縮放”。而在C中我們可以直接引用索引位置a[i]
,而在匯編中我們必須顯式地縮放索引。sll
是一種有效的乘以4的方法,sll
中的常數2表示左邊的2位(也就是:*1002,即二進制中的*100)。加法將數組基與縮放索引相加,以獲得數組引用所需字的實際地址。
我們還可以看到使用常量0或4生成的代碼。因為這些常量也是按比例縮放的,所以4表示數組中超出計算范圍的下一個元素。也就是說,如果
0($2)
指a[k]
,那么4($2)
指a[k+1]
。