2017-08-30 67 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