2017-08-30 7 views
1

リンク先:How to get a call stack backtrace?(GCC,MIPS,no frame pointer) アセンブリコードとユーザースタックを使用して関数を反復することにより、コールスタック(詳細は上記のリンクを参照)を再現しています。 私は各関数の前の$属を見つける必要があり、ほとんどの機能は、次の命令で始まる:私は簡単にオペコードから、以前の$ SPを結論付けることができ

addiu sp, sp, -80

。 問題は、スタックを使用していても$ spを変更しない関数が見つかったことです。この種の関数を呼び出す関数はスタック上の同じ起動フレームを使用しているようです。 この場合、前の$ spをどのように再現できますか?

+0

これらはネストされた関数であるとしか想像できません。とにかく、spが変更されていなければ、当然以前のspは現在のものと等しくなります。何を探したいのですか? – Jester

+0

各反復私は以前のspとraを見つけなければなりません。 raはユーザスタックに保存されているので、ユーザスタックにraをプッシュする命令からspからのraのオフセットを結論づけることができます。それが私が各反復を必要とする理由です。 – David

+0

$ spが変更されておらず、$ raが相対的に保存されている場合はどこに$ 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も参照してください。

関連する問題