2017-08-30 91 views
1

鏈接到:How to get a call stack backtrace?(GCC,MIPS,no frame pointer) 我通過使用匯編代碼和用戶堆棧迭代函數來再現調用堆棧(更多細節請參見上面的鏈接)。 我必須找到每個函數前面$ SP,大部分功能開始下面的指令:

addiu sp, sp, -80

我不難得出結論,從操作碼之前的$ SP。 問題是我發現即使使用堆棧也不會改變$ sp的函數,似乎調用這種函數的函數在堆棧上使用相同的激活幀換句話說永遠不會改變$ sp。 如何在這種情況下重現以前的$ sp?

+0

我只能想象那些是嵌套函數。無論如何,如果sp沒有改變,那麼當然前一個sp等於current,你想找什麼? – Jester

+0

每次迭代我都必須找到以前的sp和ra。將ra保存在用戶堆棧中,我可以得出ra從ra推送到用戶堆棧的指令的偏移量。這就是爲什麼我需要每次迭代的原因。 – David

+0

您只需要找到$ ra已寫入的位置,如果$ sp未被更改並且相對於$ ra已被保存,那麼問題出在哪裏?如果它沒有被保存(葉函數),它仍然在$ ra。 – Jester

回答

0

這可能會發生在優化代碼。

如果葉函數只修改臨時寄存器,並返回到其調用者代碼中的return語句,則不需要更改$ra,並且不需要該函數的堆棧幀。例如:

int caller(....) { 
    int a, b, c; 
    ... 
    c = leaf(a,b); 
    return c; 
} 
int leaf(int a, int b) { 
    return a + b; 
} 

另請參閱tail calls