2011-10-03 153 views
5

我正在研究MIPS彙編語言,並在本書中遇到了這個例子,對我來說這看起來不正確。如果是這樣,它不會是我在本書中發現的第一個錯誤。分別將C轉換爲MIPS - 嵌套數組

變量fg和分配寄存器$s0$s1和,對於陣列AB基地址分別爲$s6$s7

C代碼的例子是:

f = g - A[B[4]]; 

以及設置在對應的MIPS組件是:

lw $t0, 16($s7) 
lw $s0, 0($t0) 
sub $s0, $s1, $s0 

從我理解上面的MIPS代碼將從存儲器提供的地址加載一些隨機數據通過$t0然後從$s1中減去它並且不訪問在$s6中表示的陣列的索引$t0

從我的理解正確的MIPS彙編將沿着線:

lw $t0, 4($s7) 
add $t0, $t0, $s6 
sll $t0, $t0, 2 
lw $s0, 0($t0) 
sub $s0, $s1, $s0 

我是正確的,這是書中的錯誤還是我誤解的東西。


編輯:修正了一個錯誤校正碼MIPS由多德

+3

我認爲你是對的。做得好! – davin

+1

你的解釋非常好。事實上這個代碼沒有做到它應該做的事情的最大證明是沒有提及任何'$ s6',所以它不可能從數組'A'中檢索一個元素。 – davin

+4

假設數組A是每個元素4個字節(因爲數組B似乎是 - 您使用16的偏移量來獲取元素4,並使用lw指令獲得4個字節),您需要添加一個在這裏也乘以4(或相當於2的移位) –

回答

0

正如我指出的那樣,本書中有許多錯誤。自發現這個錯誤以來,我發現了幾個這樣的錯誤。

-1

指出,但它很可能是作者複製鏈接時之前的代碼。這將使打開鏈接在A []的內存地址填寫地方0在聲明中

lw $s0, 0($t0) 
在最終的可執行

的可能性。我不知道MIPS是否允許這種大小的偏移量(也就是最後放置A []的地址範圍)。這當然不是一種很好的方式來解釋一本書中的某些東西,無聲地打破了自己的處所,並且通常不知道發生了什麼。

+1

這將不起作用,因爲偏移量是帶符號的16位字節偏移量,「$ s6」原則上可以使用完整的32位地址範圍。這本書很可能僅僅是一個錯誤。 (另外,我不認爲任何MIPS鏈接器都會進行這種優化,因爲它會與相對偏移量非常令人討厭,並且不得不處理偏移量過大的情況) – user786653

+0

沒有一個理智的彙編器/鏈接器會這樣做。對於該指令的功能絕對不會有任何困惑。這是一個帶有reg + imm地址的顯式加載。它不像HLL的編譯器那樣可以插入任何它想要的指令。 –

4

這是任何人(可能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 

如果有人對16位和4位的整體偏移以及是否需要移位感到困惑,請讓我解釋一下。如果存儲器寬度是32位,則整個32位整數可以存儲在一個存儲器位置中。如果是這種情況,那麼數組索引與地址偏移量相同。但是,如果存儲器只有8位(1字節)寬,則32位整數存儲在4個存儲器位置(每個字節1個地址)。這就是爲什麼您需要將索引移位2(或乘以4)以獲得正確的地址偏移量。