57 votes

Que se passe-t-il si vous utilisez l'ABI Linux 32-bit int 0x80 dans un code 64-bit ?

int 0x80 sous Linux invoque toujours l'ABI 32 bits, quel que soit le mode à partir duquel il est appelé : les arguments dans le champ ebx , ecx , ... et les numéros syscall de /usr/include/asm/unistd_32.h . (Ou se bloque sur les noyaux 64 bits compilés sans CONFIG_IA32_EMULATION ).

Le code 64 bits doit utiliser syscall avec les numéros d'appel de /usr/include/asm/unistd_64.h et les args dans rdi , rsi etc. Voir Quelles sont les conventions d'appel pour les appels système UNIX et Linux sur i386 et x86-64 ? . Si votre question a été marquée comme un doublon de celle-ci, voir ce lien pour plus de détails sur la façon dont vous devrait effectuer des appels système en code 32 ou 64 bits. Si vous voulez comprendre ce qui s'est passé exactement, continuez à lire.

(Pour un exemple de comparaison de 32 bits et 64 bits sys_write voir Utilisation de l'interruption 0x80 sous Linux 64 bits )


syscall sont plus rapides que les appels système int 0x80 et utilisez donc les appels système natifs 64 bits syscall à moins que vous n'écriviez du code machine polyglotte qui s'exécute de la même manière en 32 ou 64 bits. ( sysenter retourne toujours en mode 32 bits, elle n'est donc pas utile depuis l'espace utilisateur 64 bits, bien que ce soit une instruction x86-64 valide).

En rapport : Le guide définitif des appels système de Linux (sur x86) pour savoir comment faire int 0x80 o sysenter les appels système 32 bits, ou syscall les appels système 64 bits, ou l'appel au vDSO pour les appels système "virtuels" tels que gettimeofday . Plus des informations sur ce que sont les appels système.


Utilisation de int 0x80 permet d'écrire quelque chose qui s'assemblera en mode 32 ou 64 bits. exit_group() à la fin d'un microbenchmark ou autre.

Les PDF actuels des documents psABI officiels de System V i386 et x86-64 qui standardisent les conventions d'appel de fonctions et de syscall sont liés à l'adresse suivante https://github.com/hjl-tools/x86-psABI/wiki/X86-psABI .

Voir le x86 étiquette wiki pour les guides du débutant, les manuels x86, la documentation officielle et les guides/ressources d'optimisation des performances.


Mais comme les gens continuent de poster des questions avec du code qui utilise int 0x80 en code 64 bits ou accidentellement construction de binaires 64 bits à partir de sources écrites pour 32 bits, je me demande ce que exactement se produit-il sur les Linux actuels ?

Fait int 0x80 sauvegarder/restaurer tous les registres 64 bits ? Est-ce qu'il tronque les registres en 32 bits ? Que se passe-t-il si vous passez des arcs de pointeurs dont les moitiés supérieures ne sont pas nulles ?

Cela fonctionne-t-il si vous lui passez des pointeurs 32 bits ?

1 votes

@IwillnotexistIdonotexist : Clobbering r8-r11 est la raison la moins importante ! #La raison n°1 est : ne supporte que les args / valeurs de retour 32 bits. #2 est : strace le décode mal, donc c'est difficile à déboguer. #3 est : faible performance. #La raison n°4 est : les arguments de registre ne correspondent pas à l'appel de fonction x86-64 et il utilise ebx dont l'appel est préservé. (Les classements varient selon le cas d'utilisation / débutant ou non, mais je pense que tous ces éléments l'emportent sur le fait de passer les r8-r11 tout le temps). Bref, je vais réfléchir à une meilleure intro.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X