mret

mret

RISC-V アセンブリ 参考

lyszt.netはmretおよびその他のRISC-V命令をより詳しく扱っています。

説明

mret はトラップハンドラから戻ります。トラップは、プロセッサが実行中のプログラムを停止し、ハンドラが引き継げるようにしたときに発生します。ハンドラは固定アドレスにあるルーチンです。デバイスが割り込みを発生させると、たとえば GPIO ボードのボタンなどがそうですが、それがトラップを開始します。この名前は machine-mode return の略です。

mret

トラップが開始されると、プロセッサは中断された命令のアドレスを mepc に保存し、理由を mcause に記録し、mstatus のグローバル割り込み許可ビットをクリアし、mtvec に保持されているハンドラアドレスにジャンプします。mret はこれを元に戻します。mepc のアドレスをプログラムカウンタにロードし、トラップの開始時に mstatus が保存した割り込み許可ビットを復元します。中断されたプログラムは、実行しようとしていた命令から再開します。

mret はオペランドを取りません。これがないと、プロセッサはハンドラの終端を越えて、後続のコードへと進み続けます。

割り込みは任意の 2 つの命令の間に到着する可能性があり、中断されたプログラムはそれに対する準備を一切していません。したがってハンドラは、変更するすべてのレジスタを保存し、mret の前にそれらを復元します。

ボタンハンドラはまた、mret の前にボタンの保留ビットをクリアします。そのビットがセットされたままだと、mret が割り込みを再び有効にした瞬間に同じ割り込みが再び発生します。

この例では、target のアドレスを mepc に書き込み、mret を実行してそこへジャンプします。実際のトラップの外では、これはジャンプそのものを示しています。CSR の書き込みについては csrw を参照してください。

例

la t0, target
csrw mepc, t0
mret          # pc = mepc, so execution continues at target
target:
nop