アム?呼び出された関数が入力される前に
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
によって変更されている)に応じて変更されているものを維持することだと思うが。
はい、リーフ以外の関数は '$ ra'自身を保存/復元する必要があります。 –
@PeterCordes jal命令のほかに、syscall命令は常に$ raレジスタを保持しますか?私は変更があるかどうか確認しようとしていましたが、$ raがシステムコールの後に保存されているようです。私は実際にどのように保存されているのかわかりません。 –
'syscall'は' $ ra'を使ってリターンアドレスを保存しません。別のメカニズムを使用してカーネルモードに切り替えます。 '$ ra'を保存するかどうかは、カーネルに任されます。 SPIMとMARSのドキュメントによると、システムコールは戻り値を除くすべてのregを保持しています。 Linux-MIPSシステムコールについても同じことが言えるでしょう。 –