ret
pseudolyszt.net couvre ret et d'autres instructions RISC-V plus en détail.
Description
ret retourne d'une fonction et rend le contrôle à l'appelant. Un call en attend un. Lorsqu'une fonction est appelée, l'appelant place une adresse de retour dans le registre ra (voir call et jal), et ret saute à cette adresse, qui continue juste après l'appel d'origine. C'est une pseudo-instruction qui saute vers ra.
ret ne fonctionne que lorsque ra contient encore la bonne adresse. Dans une fonction qui n'appelle rien d'autre, rien ne modifie ra entre l'entrée et la sortie. Un call à l'intérieur de la fonction écrase ra avec une nouvelle adresse de retour et efface celle dont la fonction a besoin. Une fonction qui en appelle d'autres sauvegarde son ra à l'entrée et le restaure avant ret. Sans la restauration, la fonction retourne au mauvais endroit, et le programme saute dans du code sans rapport ou boucle indéfiniment.
Par convention, une fonction place son résultat dans le registre a0 avant de retourner, et l'appelant le lit à cet endroit.
Le manuel RISC-V indique qu'un retour de procédure dans la convention d'appel standard est encodé comme un jalr avec rd=x0, rs1=x1 et un immédiat de 0. Il saute à l'adresse contenue dans x1 et n'écrit aucune adresse de lien, puisque x0 la rejette. Le manuel ajoute que les processeurs utilisent les numéros de registre dans jal et jalr comme indications pour prédire les retours de fonction, ce qui est l'une des raisons pour lesquelles la convention standard conserve l'adresse de retour dans x1.
L'exemple est la fonction complète la plus simple. square multiplie son argument par lui-même et ret renvoie le résultat. Elle n'appelle rien d'autre, donc elle ne sauvegarde et ne restaure rien. L'exécuter dans le simulateur montre le contrôle qui saute vers l'appelant.
Se développe en
jalr zero, ra, 0
L'assembleur remplace cette pseudo-instruction par la ou les instructions réelles listées ci-dessus.
Exemple
square: mul a0, a0, a0 ret # return to the caller
