2014-01-09 223 views
3

我試圖將C代碼轉換爲MIPS彙編。有以下兩個C代碼片段。問題是我的解決方案與標準解決方案不同。另外,我不瞭解標準解決方案。我希望有人能向我解釋下面兩個mips彙編代碼片斷。C代碼到MIPS彙編

首先是該任務的一些附加信息。只允許使用以下MIPS指令:lw,add,beq,bne和j
寄存器:
$ S3包含
$ S4包含Ĵ
$ S5包含ķ
32位整數的陣列的起始地址A$ S6
$ T0$ T1可用於存儲臨時變量

第一個是一個簡單的do-while循環:

do { 
    i = i + j; 
} while(A[i] == k); 

MIPS大會

loop: add $s3, $s3, $s4 // this is i = i+j 
     add $t1, $s3, $s3 // from now on 
     add $t1, $t1, $t1 // I cant follow anymore 
     add $t1, $t1, $s6 // What happens in these three lines? 
     lw $t0, 0($t1) // 0($t1) is new for me. What does this zero do? 
     beq $t0, $s5, loop 

現在第二個C代碼:

if (i == j) 
    i = i + A[k]; 
else if(i == k) 
    i = i + A[j]; 
else 
    i = i + k; 

這裏是MIPS彙編代碼:

 bne $s3, $s4, Else1 // this line is if(i==j) 
     add $t1, $s5, $s5 // from here on 
     add $t1, $t1, $t1 // till 
     add $t1, $t1, $s6 // 
     lw $t0, 0($t1) // 
     add $s3, $s3, $t0 // here I don't understand 
     j done 
ELSE1: bne $s3, $s5, Else2 // this line is if(i==k) 
     add $t1, $s4, $s4 // The same game as above 
     add $t1, $t1, $t1 
     add $t1, $t1, $s6 
     lw $t0, 0($t1) 
     add $s3, $s3, $t0 // till here 
     j done 
ELSE2: add $s3, $s4, $s5 

任何人都可以解釋我真正的推移?這將是非常有幫助的

回答

2

lw是負載。這裏的模式是間接尋址,最常見的是:

lw $t2, ($t0) 

但你也可以包括字節偏移,

lw $t2, 4($t0) # load word at RAM address ($t0 + 4) into register $t2 

編譯器只是把0佔位符的非偏移版本。

因此,要加載A[i]您需要做兩件事。取基地址A[],然後加i乘以sizeof(A[0])。我猜測A中的值是32位。

add $t1, $s3, $s3 

$t1 = j + j2 * j

add $t1, $t1, $t1 

$t1 = $t1 + $t1j +j +j +j4 * j

那麼它爲什麼做這種方式?那麼,就時鐘週期而言,直接乘法運算速度很慢。接下來的選擇是換班,但在這種情況下,編譯器設計人員決定增加兩個增加值。

add $t1, $t1, $s6 

我猜$s6A[]基址。所以最終'$ t1 = A [] + 4 * j`

+0

確定。現在一切似乎都變得更清晰了。但我有問題的抵消。 ** lw $ t2,0($ t0)**相當於將地址加載到**($ t0 + 0)**。我可以在上面的例子中省略「0」,只是使** lw $ t2,($ t0)**? – tumbler

+0

是的,在我發現的MIPS彙編頁面中,'lw $ t2,($ t0)'是一個有效的表單。 – woolstar

+0

你好,我問題出現了。設計師決定使用兩個加法而不是乘法,也許是因爲你說的性能問題。但爲什麼設計師仍然使用4的乘法?當然,數組中的數字是32位整數。所以,它們是4字節大,但我們不知道變量i,j和k有多大。也許每個人都是4字節大。那麼我們不需要將A []與4相乘得到下一個值?我認爲設計者認爲變量是1個字節大。這是真的嗎? – tumbler

2

也許。最有趣的和不理解的代碼如下:加$ T1,

add $t1, $s5, $s5 
add $t1, $t1, $t1 
add $t1, $t1, $s6 

驗證碼數乘以4 $ S5,並將其存儲在$ T1,然後添加到$ T1 $ S6。這相當於:

​​

你理解了這個之後,代碼看起來就更清晰了。

有關lw $t0, 0($t1)

你可以在地址使用偏移點。這裏的偏移量爲0.

0

我有一個答案。循環,a是元素數組有基本地址:0x0FE3B128。 非常感謝.. 這是我的家庭作業,我不確定它是否正確。

for(i=1; i!=20;i+=3){ 
 
     a[i]= a[5]+1; 
 
     } 
 
lui $s0, 0x0FE3 
 
ori $s0, $0, B128 
 
lw  $t1, 20($s0) 
 
addi $s1, $0, 1 
 
addi $s2, $0, 20 
 
LOOP  beq $s1, $s2, DONE 
 
     add $t1, $t1, $s1 
 
     sll $t1, $t1, 2 
 
     sw $t2, 0($t1) 
 
     addi $s1, $0, 3 
 
      j LOOP 
 
DONE