mret
lyszt.net couvre mret et d'autres instructions RISC-V plus en détail.
Description
mret revient depuis un gestionnaire de trappe. Une trappe se produit lorsque le processeur arrête le programme qu'il exécute afin qu'un gestionnaire puisse prendre le relais. Un gestionnaire est une routine située à une adresse fixe. Un périphérique déclenche une interruption, comme le bouton de la carte GPIO, ce qui démarre une trappe. Le nom signifie retour en mode machine.
mret
Lorsqu'une trappe démarre, le processeur stocke l'adresse de l'instruction interrompue dans mepc, enregistre la raison dans mcause, efface le bit d'activation globale des interruptions de mstatus et saute à l'adresse du gestionnaire contenue dans mtvec. mret annule cela. Il charge le compteur de programme avec l'adresse contenue dans mepc et restaure le bit d'activation des interruptions que mstatus avait sauvegardé au début de la trappe. Le programme interrompu reprend alors à l'instruction qu'il était sur le point d'exécuter.
mret ne prend aucun opérande. Sans lui, le processeur continue au-delà de la fin du gestionnaire dans le code qui suit.
Une interruption peut survenir entre deux instructions quelconques, et le programme interrompu ne s'y est pas préparé. Un gestionnaire sauvegarde donc chaque registre qu'il modifie et les restaure avant mret.
Un gestionnaire de bouton efface également le bit en attente du bouton avant mret. Si ce bit reste activé, la même interruption se déclenche à nouveau dès que mret réactive les interruptions.
L'exemple écrit l'adresse de target dans mepc et exécute mret, qui saute à cet endroit. En dehors d'une véritable trappe, cela montre le saut à lui seul. Voir csrw pour écrire dans un CSR.
Exemple
la t0, target csrw mepc, t0 mret # pc = mepc, so execution continues at target target: nop
