x86_64 Assemblée Appel Système Linux Confusion
Je suis actuellement en apprentissage de la langue de l'Assembly sur Linux. J'ai été en utilisant le livre "Programmation à Partir de la base" et tous les exemples sont en 32 bits. Mon OS est en 64 bits et j'ai essayé de le faire tous les exemples en 64 bits. J'ai de la difficulté cependant:
.section .data
.section .text
.global _start
_start:
movq $60, %rax
movq $2, %rbx
int $0x80
Ce juste des appels à Linux, la sortie de l'appel Système ou il faut. Au lieu de cela, il provoque un SEG FAULT et quand je au lieu de faire ce
.section .data
.section .text
.global _start
_start:
movq $1, %rax
movq $2, %rbx
int $0x80
il fonctionne. Clairement le problème, c'est la valeur que j' %rax. La valeur $1 que j'utilise dans le deuxième exemple est ce que la Programmation à Partir de la base", a déclaré à utiliser plusieurs sources sur Internet, ont dit que le Système 64 bits Numéro d'Appel est de 60$. Référence
Ce que je fais mal? Aussi ce que les autres questions dois-je faire attention et que dois-je utiliser pour une référence? Juste au cas où vous avez besoin de savoir, je suis sur le Chapitre 5 de la Programmation à Partir Du Sol.
OriginalL'auteur Hudson Worden | 2011-12-14
Vous devez vous connecter pour publier un commentaire.
Vous êtes en cours d'exécution dans un surprenant différence entre les architectures i386 et x86_64: ils n'utilisent pas le même système de mécanisme d'appel. Le code correct est:
Interrompre
0x80
appelle toujours 32 bits, les appels système. Il est utilisé pour permettre à des applications 32 bits pour fonctionner sur les systèmes 64 bits.Pour l'application de l'apprentissage, vous devriez probablement essayer de suivre le tutoriel exactement, plutôt que de traduire à la volée à 64 bits -- il y en a quelques autres différences de comportement que vous êtes susceptible de rencontrer. Une fois que vous êtes familier avec i386, puis vous pouvez ramasser x86_64 séparément.
On devrait utiliser
%rdi
pour le premier appel système argument, pas%rbx
.Merci pour attraper celui - fixe.
sysenter
ne fonctionne pas sur mon système. L'instruction correcte estsyscall
.est la AMD d'origine version, tandis que
sysenter
est l'Intel d'origine de la version. Plus de détails ici: wiki.osdev.org/SYSENTEROriginalL'auteur duskwuff
veuillez lire ce Quelles sont les conventions d'appel pour UNIX & appels système Linux sur x86-64
et notez que l'utilisation de
int 0x80
pour syscall sur les systèmes x64 est une vieille couche de compatibilité. vous devez utilisersyscall
instruction sur les systèmes x64.vous pouvez toujours utiliser cette vieille méthode, mais vous avez besoin de compiler vos fichiers binaires dans un x86 mode, consultez votre compilateur/assembleur manuel pour plus de détails.
syscall
passysenter
! J'ai écrit un plus de réponse pour expliquer la confusion entre les deux.OriginalL'auteur zed_0xff
duskwuffrépondre les points correctement le mécanisme pour les appels-système est différent pour la version 64 bits x86 Linux par rapport à 32 bits de Linux.
Cependant, cette réponse est incomplète et trompeuse pour un couple de raisons:
int 0x80
a été très lente sur le Pentium 4. Linus Torvalds codé en place une solution à l'aide de laSYSENTER
/SYSEXIT
instructions (qui avait été introduit par Intel à travers le Pentium Pro era, mais qui ont été buggy et donna pas d'intérêt pratique). Donc moderne 32 bits des systèmes Linux utilisent effectivementSYSENTER
, pasint 0x80
.SYSENTER
etSYSEXIT
. Ils en fait, l'utilisation le très semblableSYSCALL
/SYSRET
instructions.Que souligné dans les commentaires,
SYSENTER
n'a pas fait le travail sur de nombreux Linux 64 bits des systèmes d'—à savoir 64 bits AMD systèmes.C'est un certes situation de confusion. Le détails sanglants sont ici, mais qu'il se résume à ceci:
Il apparaît que sur un Intel CPU en mode 64 bits, vous pouvez vous en sortir avec l'aide de
SYSENTER
parce qu'il fait la même chose queSYSCALL
, mais ce n'est pas le cas pour les systèmes AMD.Ligne du bas: toujours utiliser
SYSCALL
sur Linux 64 bits des systèmes x86. C'est ce que le x86-64 ABI fait précise. (Voir ce grand wiki réponse pour plus de détails.)OriginalL'auteur Dan Lenski
Tout à fait beaucoup de choses ont changé entre les architectures i386 et x86_64, y compris à la fois l'instruction d'aller dans le noyau et dans les registres utilisés pour transporter les arguments d'appel système. Voici le code équivalent au vôtre:
Citant cette réponse à une question connexe:
OriginalL'auteur Adam Zalcman
Si vous cochez
/usr/include/asm/unistd_32.h
de sortie correspond à1
mais dans/usr/include/asm/unistd_64.h
de sortie correspond à60
.OriginalL'auteur Yeke