Qu'est-ce que Adresse de retour ?
Adresse à laquelle revenir une fois la fonction terminée. En RISC-V, l'instruction jal place l'adresse de l'instruction suivante dans ra (x1) ; en x86, l'instruction call l'empile.
Nom japonais: リターンアドレス
« Adresse de retour » apparaît dans 10 questions d'entraînement réparties sur 4 thèmes, dont ISA et assembleur, CPU et architecture, Éditeurs de liens, chargeurs et exécutables.
Domaine: ISA et assembleur
Comment un appel la sauvegarde
Un appel doit enregistrer l'endroit où l'exécution doit reprendre, c'est-à-dire l'adresse de l'instruction qui suit l'appel. En RISC-V, jal (jump and link) écrit PC + 4 dans un registre, par convention ra (x1), puis effectue le saut ; le retour se fait par ret, une pseudo-instruction équivalant à jalr x0, 0(ra). Les appels via des pointeurs de fonction, des fonctions virtuelles et des stubs de bibliothèques partagées utilisent jalr avec une cible dans un registre. En x86, call empile l'adresse de retour et ret la dépile dans le pointeur d'instruction : la pile la contient donc toujours.
Fonctions feuilles et non feuilles
Comme chaque jal écrase ra, une fonction RISC-V qui appelle d'autres fonctions doit d'abord sauvegarder sa propre adresse de retour. Un prologue typique est addi sp, sp, -16 pour allouer un cadre sur la pile, qui croît vers le bas, puis sw ra, 12(sp) et sw s0, 8(sp) pour sauvegarder ra et un registre préservé par l'appelé. L'épilogue les recharge, restaure sp et exécute ret. Une fonction feuille, qui n'appelle rien, peut laisser ra dans son registre et n'a parfois besoin d'aucun cadre de pile, ce qui rend les petites fonctions peu coûteuses.
Questions fréquentes
Où est stockée l'adresse de retour en RISC-V ?
Dans le registre ra (x1), écrit par jal ou jalr lors de l'appel. Une fonction non feuille la copie dans son cadre de pile avant d'effectuer ses propres appels et la restaure avant ret.
Quelle différence entre call/ret en x86 et jal/ret en RISC-V ?
En x86, call empile toujours l'adresse de retour et ret la dépile, tandis qu'en RISC-V, jal la place dans un registre et ne touche la mémoire que si la fonction choisit de la sauvegarder.
Pourquoi écraser l'adresse de retour est-il dangereux ?
Au retour de la fonction, le CPU saute à l'adresse qui s'y trouve : un attaquant qui l'écrase par un dépassement de tampon peut donc prendre le contrôle du programme.