2014-07-15 69 views
3

我完全無法理解MIPS的堆棧。堆棧中的空間是通過減去寄存器來分配的,堆棧隨着程序的方向增長,當堆棧增長太多時,它會通過覆蓋(或者至少試圖)程序而溢出。一旦執行該函數,我必須通過添加先前減去的相同值來刪除堆棧。這對我來說很好。不過,我被告知,當我保存參數時,我必須分配四個空格,對應於四個第一個參數($ a0- $ a3),並且從不使用它們(如所述的here)。爲什麼?另外,當我構建堆棧時,我必須保存額外的參數。我是否應該保存「不額外」的論據? 例如這個C程序的組件:MIPS的堆棧會導致我的大腦溢出

void f (int x, int y, int z) { 
    int array[5], a, b; 

    if (x >= y && x != z) 
     g(x+1, y+2, z+3, 4, 5); 
    else 
     h(x-1, y-2, z-3, 4, 5, 6, 7); 

    while (z != 0) 
     x++ 
} 

我應該保存$ A0〜$ A3在各自堆棧位置?我應該將它們保存在$ s0- $ s3?如果我沒有部分,我應該不是保存嗎?

+0

已鏈接是描述一個微軟特定調用約定的頁面。這不是在MIPS CPU上使用堆棧的唯一方法。 –

+0

呃,你不需要在C中分配任何堆棧空間。實際上,C不需要堆棧。你用自動存儲持續時間聲明變量,編譯器完成剩下的工作。此外,+1爲braindamaged微軟調用約定。 – EOF

+0

@EOF對不起,我的意思是如何組裝C程序。 – gabrieljcs

回答

3

這只是一個慣例,參數通過這種方式傳遞。如果你編寫一個程序,並且你的一個函數正在調用你寫的另一個函數,你也可能決定通過堆棧上的所有參數(而不是$ a0- $ a3)或者做任何不同的事情......

但是當你調用一個不是你寫的函數(例如一個由C編譯器生成的函數),或者你的函數被這樣的函數調用時,你必須假設你寫的函數的行爲不像這裏描述的那樣。

當我保存參數時,我必須分配四個空格,對應於四個第一個參數($ a0- $ a3)並且從不使用它們(如此處所述)。爲什麼?

早期的MIPS處理器是爲高端計算機設計的,所以這些約定背後的主要目標是速度而不是可用性。

我只是在想這個「奇怪」的約定:有很多情況下,這個約定會產生儘可能快的代碼。所以這就是原因。

我是否應該保存「不多餘」的參數呢?

您可以這樣做;但是您調用的函數將忽略存儲在那裏的數據。當你編寫一個自己的編譯器(我已經做過)時,當你在堆棧上存儲「非額外參數」時應該容易得多 - 所以這可能是一個理由。

2

MIPS調用約定從Wikipedia

32位MIPS最常用的1調用約定是O32 [2]其中ABI通過第一四個參數的函數在寄存器$ $ A0〜A3 ;隨後的參數在棧上傳遞。如果被調用者需要保存它的參數,堆棧中的空間被保留爲$ a0- $ a3,但是調用者不在那裏存儲這些寄存器。返回值存儲在寄存器$ v0中;第二個返回值可以存儲在$ v1中。

可以修改$t0,...... $t9寄存器而不保存在棧中,但可以通過任何函數代碼調用進行修改。如果您需要使用$s0,...,$s7,則必須將它們保存在堆棧中並在返回之前將其還原。