IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
logo

FAQ AssembleurConsultez toutes les FAQ

Nombre d'auteurs : 9, nombre de questions : 56, dernière mise à jour : 8 décembre 2017  Ajouter une question

 

Cette FAQ a été réalisée à partir des questions fréquemment posées sur le forum Assembleur de Developpez.com et de l'expérience personnelle des auteurs. Nous tenons à souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle propose soient correctes. Les auteurs font le maximum, mais l'erreur est humaine. Cette FAQ ne prétend pas non plus être exhaustive ; vous pouvez la compléter avec vos propres questions/réponses ou proposer des corrections ou des compléments à des questions/réponses existantes.

Nous espérons que cette FAQ saura répondre à un maximum de vos questions. Nous vous en souhaitons une bonne lecture.

L'équipe Assembleur de Developpez.com.

SommaireF.A.Q. Assembleur x86 / 64Questions spécifiques à la programmation (9)
précédent sommaire
 

Windows :

  • GoAsm ;
  • MASM (64) : fait partie du SDK de Windows (exécutable ml64.exe).

Cross plate-forme (au minimum Linux & Windows) :
  • FASM ;
  • YASM (syntaxe NASM) ;
  • Gas (au travers de GCC par exemple).

(merci à Gamera pour le lien vers FASM)

Mis à jour le 29 avril 2007 Neitsa

Visual C++ ne permet plus l'utilisation de l'inlining Assembleur (Assembleur incorporé dans un programme en C ou C++).

Pour pallier ce problème vous pouvez :

Mis à jour le 29 avril 2007 Neitsa

Il n'existe plus qu'une seule convention d'appel en mode 64 bits. Cette dernière est semblable au type d'appel _fastcall, ce qui implique que les arguments, lors d'un appel de fonction, sont d'abord passés au travers des registres.

Pour Windows :

  • lorsqu'il y a 4 arguments entiers (ou moins), ceux-ci sont passés par les registres suivants, dans cet ordre précis : RCX, RDX, R8 et R9 ;
  • lorsqu'il y a plus de 4 arguments entiers, ceux-ci sont poussés sur la pile ;
  • les arguments à virgule flottante (double ou float) sont pris en charge par les registres XMM (dans cet ordre précis) : XMM0, XMM1, XMM2, XMM3 ;
  • les arguments supérieurs à 64 bits (par ex. les doubles quadword [128 bits]) poussent leurs adresses sur la pile.

Ref. : Overview of x64 Calling Conventions
Ref. : Parameter Passing


Pour Linux :
  • Lorsqu'il y a 6 arguments entiers (ou moins), ceux-ci sont passés par les registres suivants, dans cet ordre précis : RDI, RSI, RDX, RCX, R8, R9.
  • Lorsqu'il y a plus de 6 arguments entiers, ceux-ci sont poussés sur la pile.
  • Les arguments à virgule flottante (double ou float) sont pris en charge par les registres XMM (dans cet ordre précis) : XMM0 à XMM7.
  • Les arguments supérieurs à 64 bits (par ex. les doubles quadword [128 bits]) poussent leurs adresses sur la pile.

Ref. : AMD64 ABI.

Mis à jour le 29 avril 2007 Neitsa

Pour Windows :

La valeur renvoyée par une fonction est placée dans le registre RAX, à moins que le résultat soit un type en virgule flottante, qui est alors renvoyé dans XMM0.

Pour Linux :

La valeur renvoyée par une fonction est placée dans le registre RAX et/ou RDX, à moins que le résultat soit un type en virgule flottante, qui est alors renvoyé dans XMM0 et/ou XMM1. Le retour de fonction peut aussi s'effectuer sous ST(0) ou ST(1) si la fonction manipule des données via le coprocesseur mathématique à virgule flottante (x87).

Mis à jour le 29 avril 2007 Neitsa

Pour Windows :

  • d'un appel à l'autre, les registres suivants doivent être préservés : RBX, RBP, RDI, RSI, R12 à R15, XMM6 à XMM15 ;
  • les registres suivants sont volatils et peuvent donc être détruits dans la fonction appelée : RAX, RCX, RDX, R8 à R11, ST(0) à ST(7), XMM0 à XMM5.

Ref. : Register Usage
Ref. : Caller/Callee Saved Registers


Pour Linux :
  • d'un appel à l'autre, les registres suivants doivent être préservés : RBX, RBP, R12 à R15 ;
  • les registres suivants sont volatils et peuvent donc être détruits dans la fonction appelée : RAX, RCX, RDX, RSI, RDI, R8 à R11, ST(0) à ST(7), XMM0 à XMM15.

Mis à jour le 29 avril 2007 Neitsa

Contrairement à ce qu'avait annoncé dans un premier temps Microsoft la réponse finale et courte est : oui, sauf dans les drivers.
Pour préciser cette réponse, Microsoft annonçait que la commutation de contexte (context switch) effaçait les registres ST(x) et XMM. Toutefois cette information s'est révélée fausse et a été corrigée par un responsable du programme Visual C++ et un programmeur du groupe Kernel chez Microsoft :

"Let them know that the OS does preserve state of x87 and MMX registers on context switches."
[...]
"For user threads the state of legacy floating point is preserved at context switch. But it is not true for kernel threads. Kernel mode drivers can not use legacy floating point instructions."

Mis à jour le 29 avril 2007 Neitsa

La procédure (ou fonction) appelante est responsable de l'allocation de l'espace nécessaire sur la pile pour la procédure appelée. Elle (la procédure appelante) doit toujours allouer suffisamment d'espace pour les 4 registres en paramètres même si la procédure appelée ne nécessite pas autant d'arguments. La question est assez complexe, pour plus d'informations voir la référence ci-après :

Ref. : Stack Allocation

Mis à jour le 29 avril 2007 Neitsa

Bien que la pile utilise des quadruples mots (8 octets soit 64 bits), le pointeur de pile (RSP) doit toujours être aligné sur un multiple de 16 avant d'appeler une API.

Ref. : AMD64 ABI Ref. : Stack Allocation

Pour se prémunir de ce problème, on peut utiliser un code comme celui-ci :

Code asm : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
  
PUSH RSP             ; sauvegarde la position courante de RSP sur la pile 
PUSH [RSP]           ; garde une autre copie sur la pile 
AND SPL,0F0h         ; ajuste RSP pour aligner la pile au cas où elle ne le serait pas. 
                     ; 
                     ;  paramètre(s) de l'API s'il y a lieu. 
                     ; 
SUB RSP, 32d         ; ajuste RSP pour la sauvegarde des paramètres (32d = 0x20) 
CALL API 
ADD RSP, xx          ; nettoie la pile (avec xx = 32d + (nombre de paramètres poussés * 8)) 
POP RSP              ; restaure RSP à sa valeur originale.
N.B. Certaines API supportent une pile mal alignée sans déclencher d'exception. Certaines déclenchent une exception en interne et rétablissent (toujours en interne) une pile alignée. D'autres encore ne supportent aucunement une pile mal alignée. Dans le doute : alignez la pile avant l'appel.

Mis à jour le 29 avril 2007 Neitsa

Nom du programme à compiler: hello.asm

====== Compilation =======

Code shell : Sélectionner tout
$ nasm -f elf64 -o hello.o hello.asm

L'option -f est nécessaire pour l'édition de liens.
L'option elf64 permet de préciser que c'est un programme 64 bits.
L'option -o permet de définir le fichier objet de sortie (dans notre exemple hello.o).

====== Edition de liens =======
Code shell : Sélectionner tout
$ ld -m elf_x86_64 -o hello hello.o

L'option elf_x86_64 précise l'architecture cible.
L'option -o permet de définir le fichier exécutable de sortie (dans notre exemple hello).

====== Exécution =======
Code shell : Sélectionner tout
$ ./hello

Mis à jour le 10 avril 2017

Proposer une nouvelle réponse sur la FAQ

Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour ça


Réponse à la question

Liens sous la question
précédent sommaire
 

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2024 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.