0xa2 est le numéro de syscall. Le noyau l'utilise pour décider de la fonction réelle à exécuter, puisque la fonction syscall
L'instruction elle-même ne contient aucune information.
Quant à rax
il fait être utilisé. Pour continuer la tradition commencée dans les anciens jours, les eax
est un alias pour les 32 bits inférieurs de rax
. Cependant, il existe une particularité peu connue de l'architecture x64 : chaque fois que vous modifiez la partie basse de 32 bits, les 32 bits supérieurs être mis à zéro . Donc, en fait mov eax, 0xa2
est équivalent à mov rax, 0xa2
sauf que son encodage est plus court. NASM, ou as -O2
se chargera même de l'optimisation pour vous.
Les trois dernières instructions effectuent la gestion des erreurs. Dans le cas %rax
est comprise entre -1 et -4095, cela signifie que la syscall a renvoyé une erreur, pour tout Appel système Linux. Voici comment cela se présente dans la source originale :
cmpq $-4095, %rax /* Check %rax for error. */
jae __syscall_error /* Branch forward if it failed. */
ret /* Return to caller. */
Vous voyez la mauvaise cible pour le jae
parce que vous désassemblez un objet relocalisable, et les champs relocalisables ont été mis à 0 car ils seront corrigés au moment de la liaison finale.
Pour voir les cibles de relocalisation, ajouter -r
passer à objdump
ligne de commande :
0000000000000000 <sync>:
0: b8 a2 00 00 00 mov $0xa2,%eax
5: 0f 05 syscall
7: 48 3d 01 f0 ff ff cmp $0xfffffffffffff001,%rax
d: 0f 83 00 00 00 00 jae 13 <sync+0x13>
f: R_X86_64_PC32 __syscall_error-0x4
13: c3 retq
Vous pouvez voir que les octets à l'offset f
sera corrigé de façon à ce que le saut aille vers __syscall_error
.
Lire https://cs.lmu.edu/~ray/notes/syscalls/ pour plus d'informations sur les syscalls.
Aussi Le guide définitif des appels système de Linux article de blog.