2017-10-23 7 views
0

私はMIPSの学習を始めた学生です。

私は$のRA(リターンアドレス)が呼び出し先セーブ(保存)するか否かについては、オンラインを検索しています。いくつかのテーブルは、それがそうでないことを他のいくつかの状態で保存されている呼び出し先だと述べています。

私は$ Raが、それは、呼び出し元保存レジスタの意味呼び出し先保存レジスタではないと思います。

$ raがcalleeで保存された登録簿の場合、問題があると思います。 jalを使って関数(サブルーチン)を呼び出すと、jal命令の後に$ raがPC + 4に変更されるため、呼び出し先関数が以前の$ ra値を保持することはできません。呼び出し元関数は事前に$ raをスタックに保存する必要があります。だから、この場合を考えると、$ raは呼び出し元に保存されたレジスタになります。

正しいですか?私は修正

+1

はい、リーフ以外の関数は '$ ra'自身を保存/復元する必要があります。 –

+0

@PeterCordes jal命令のほかに、syscall命令は常に$ raレジスタを保持しますか?私は変更があるかどうか確認しようとしていましたが、$ raがシステムコールの後に保存されているようです。私は実際にどのように保存されているのかわかりません。 –

+0

'syscall'は' $ ra'を使ってリターンアドレスを保存しません。別のメカニズムを使用してカーネルモードに切り替えます。 '$ ra'を保存するかどうかは、カーネルに任されます。 SPIMとMARSのドキュメントによると、システムコールは戻り値を除くすべてのregを保持しています。 Linux-MIPSシステムコールについても同じことが言えるでしょう。 –

答えて

2

アム?呼び出された関数が入力される前に

jal命令はすでに$raに値を書き込みます:あなたはすでに判明したよう

$raは非常に特殊なケースです。したがって、呼び出し関数はすでに$raレジスタを "破棄"します。

しかし、誰かが既にあなたに非常によく似質問を:

Whether $ra register callee saved or caller saved in mips?

一つの答えは、関数呼び出しことを想定することはできませんので、呼び出された関数$raレジスタを変更することが許可されていることを指摘$raには本当にリターンアドレスが含まれています。その答えで与えられた例は次のとおりです。

move $v0,$ra 
li $ra,0 
jr $v0 

JAL命令のほかに、システムコール命令は常に$ RAのレジスタを保存しますか?

syscall命令は、どのレジスタにもアクセスしない1つの単一CPU命令ですが、これは文書化されています。

実際のMIPS CPUでは、syscall命令は、x86 CPU上で「ソフトウェア割り込み」と呼ばれる命令を実行します。ソフトウェア割り込みは特殊な関数呼び出しです。しかしsyscall命令が$raレジスタにだけ特別な命令を使用してアクセスすることができます(MIPS R4400 CPU上EPCという名前)特殊レジスタに戻りアドレスを書き込みませんjal命令とは異なり

呼び出される関数(「例外ハンドラ」)はもちろんレジスタを変更します。そして、その関数が他の関数を呼び出すと、$raレジスタが変更されます。

私は、ほぼすべてのオペレーティングシステムがすべてのレジスタが、明示的に文書化する(Linux $v0$v1$a3の場合にsyscallによって変更されている)に応じて変更されているものを維持することだと思うが。

関連する問題