GNU/Linux >> Tutoriels Linux >  >> Linux

x86_64 Assemblage Linux System Call Confusion

Beaucoup de choses ont changé entre i386 et x86_64, y compris à la fois l'instruction utilisée pour entrer dans le noyau et les registres utilisés pour transporter les arguments d'appel système. Voici un code équivalent au vôtre :

.section .data

.section .text
.global _start
_start:
movq $60, %rax
movq $2, %rdi
syscall

Citant cette réponse à une question connexe :

Les numéros d'appel système se trouvent dans le code source Linux sous arch/x86/include/asm/unistd_64.h. Le numéro d'appel système est passé dans le registre rax. Les paramètres sont en rdi, rsi, rdx, r10, r8, r9. L'appel est invoqué avec l'instruction "syscall". L'appel système écrase le registre rcx. Le retour est en rax.


Vous rencontrez une différence surprenante entre i386 et x86_64 :ils n'utilisent pas le même mécanisme d'appel système. Le bon code est :

movq $60, %rax
movq $2,  %rdi   ; not %rbx!
syscall

Interrompre 0x80 appelle toujours les appels système 32 bits. Il est utilisé pour permettre aux applications 32 bits de s'exécuter sur des systèmes 64 bits.

À des fins d'apprentissage, vous devriez probablement essayer de suivre exactement le didacticiel, plutôt que de traduire à la volée en 64 bits - il existe quelques autres différences de comportement importantes que vous risquez de rencontrer. Une fois que vous êtes familiarisé avec i386, alors vous pouvez récupérer x86_64 séparément.


veuillez lire ceci Quelles sont les conventions d'appel pour les appels système UNIX et Linux sur x86-64

et notez que l'utilisation de int 0x80 pour syscall sur les systèmes x64 est une ancienne couche de compatibilité. vous devez utiliser syscall instructions sur les systèmes x64.

vous pouvez toujours utiliser cette ancienne méthode, mais vous devez compiler vos binaires en mode x86, consultez le manuel de votre compilateur/assembleur pour plus de détails.


La réponse de duskwuff indique correctement que le mécanisme des appels système est différent pour Linux x86 64 bits par rapport à Linux 32 bits.

Cependant, cette réponse est incomplète et trompeuse pour plusieurs raisons :

  • Le changement a en fait été introduit avant que les systèmes 64 bits ne deviennent populaires , motivé par le constat que int 0x80 était très lent sur Pentium 4. Linus Torvalds a codé une solution en utilisant le SYSENTER /SYSEXIT instructions (qui avaient été introduites par Intel à l'époque du Pentium Pro, mais qui étaient boguées et n'offraient aucun avantage pratique). Donc les systèmes Linux 32 bits modernes utilisent en fait SYSENTER , pas int 0x80 .
  • Les noyaux Linux x86 64 bits n'utilisent pas réellement SYSENTER et SYSEXIT . Ils utilisent en fait le très similaire SYSCALL /SYSRET instructions.

Comme indiqué dans les commentaires, SYSENTER ne fonctionne pas réellement sur de nombreux systèmes Linux 64 bits —à savoir AMD 64 bits systèmes.

C'est une situation certes déroutante. Les détails sanglants sont ici, mais cela revient à ceci :

Pour un noyau 32 bits, SYSENTER/SYSEXIT sont le seul couple compatible [entre les CPU AMD et Intel]

Pour un noyau 64 bits en mode Long uniquement… SYSCALL/SYSRET sont le seul couple compatible [entre les CPU AMD et Intel]

Il semble que sur un Intel CPU en mode 64 bits, vous pouvez vous en sortir en utilisant SYSENTER car il fait la même chose que SYSCALL , cependant ce n'est pas le cas pour les systèmes AMD.

Conclusion :utilisez toujours SYSCALL sous Linux sur des systèmes x86 64 bits . C'est ce que spécifie réellement l'ABI x86-64. (Voir cette excellente réponse wiki pour encore plus de détails.)


Linux
  1. Linux - Pourquoi les utilitaires Linux n'utilisent-ils pas un appel système pour obtenir l'heure actuelle ?

  2. Meilleures pratiques de codage pour la programmation système Linux en langage C - Partie 1

  3. Comment mmaper la pile pour l'appel système clone() sous Linux ?

  4. Table d'appels système Linux ou aide-mémoire pour l'assemblage

  5. Appel système Linux le plus rapide

Configuration système requise pour Kali Linux

Commande d'arrêt de Linux

Commande Fsck sous Linux

Linux est-il un système d'exploitation ou un noyau ?

Documenter la disponibilité du système sous Linux

Comment vérifier que le système Linux est 32 bits ou 64 bits ?