Il existe deux manières principales de programmer avec l'assembleur. La première consiste à créer le programme entier avec l'assembleur et l'autre à n'écrire que certaines fonctions avec l'assembleur. Le premier n'est pas réaliste compte tenu de la faible lisibilité de l'assembleur. C'est pourquoi ce dernier devient le courant dominant. En écrivant certaines fonctions en assembleur et d'autres en C, la maintenabilité et une vitesse efficace élevée peuvent être obtenues.
Cet article suppose un environnement Linux. L'assembleur dépend fortement de l'environnement et ne fonctionnera que sous Linux. Veuillez préparer les logiciels suivants dans l'environnement Linux.
Écrivez le programme C main.c ci-dessous et le programme assembleur add.asm avec un éditeur et enregistrez-les.
main.c
#include <cstdio>
extern int asm_add(int a, int b);
int main()
{
int a, b;
a = 1;
b = 2;
int ans = asm_add(a, b);
printf("%d\n", ans);
return 0;
}
add.asm
section .text
global _sm_add
asm_add:
enter 0,0
mov eax, edi
mov ebx, esi
add eax, ebx
leave
ret
Compilez main.c pour générer un fichier objet.
gcc -c -o main.o main.c
Compilez add.asm pour générer un fichier objet.
#### **` nasm -g -f elf64 -o add.o add.asm `**
Liez le fichier objet généré.
gcc -o add -lc -g main.o add.o -o add
Vous avez maintenant le fichier exécutable ajouté.
Quand tu cours
``` 3 ```
S'affiche à l'écran.
# Commentaire côté programme C
Je vais expliquer la source de C. Code très simple. Tout d'abord, la fonction ```int add (int a, int b) `` `est déclarée dans extern.
Dans les fichiers d'assemblage, les fichiers d'en-tête ne peuvent pas gérer les connexions entre les objets comme vous le feriez normalement en C. Par conséquent, déclarez-le avec extern et spécifiez le lien externe.
Les autres parties sont identiques à un programme C normal.
De même, en C ++, vous pouvez appeler des fonctions créées par l'assembleur.
# Commentaire côté assembleur
Puisqu'il s'agit d'un code court, il est expliqué ligne par ligne.
#### **` section .texte Signifie le début du code..Outre le texte.data(Déclaration des données initialisées)、.bss(Déclaration de données non initialisées)Il existe une section de, mais elle est omise dans ce code.`**
global _asm_add
Marqueur_asm_Add est spécifié globalement afin qu'il puisse être référencé à partir d'autres codes.
Est un marqueur. En dessous se trouve la fonction asm_Le corps de add.
``` enter 0,0 ```Est une instruction pour construire un cadre de pile. Un cadre de pile est une destination de stockage pour les données développées en mémoire. Il stocke les variables utilisées dans la fonction et l'adresse de l'instruction à renvoyer après la fin de la fonction.
mov eax, edi mov ebx, esi
Déplace les arguments a et b vers le registre à usage général. Dans l'environnement Linux, les arguments de fonction sont stockés dans des registres et transmis. Cela permet de réduire la fréquence d'accès à la mémoire et d'accélérer le processus. Il y a une décision un-à-un quant à quel registre les données de quel argument de la fonction sont stockées. Le tableau de correspondance est présenté ci-dessous.
|S'inscrire|argument|
|:-------:|:------:|
| edi |Premier argument|
| esi |Deuxième argument|
| edx |Troisième argument|
| ecx |Quatrième argument|
| r8d |Cinquième argument|
| r9d |Sixième argument|
A partir du 7ème argument, il est échangé via la pile. Cependant, compte tenu de la vitesse d'exécution et de la lisibilité, vous n'avez probablement pas besoin de plus que le 7ème argument.
add eax, ebx
Le contenu d'ebx et le contenu d'eax sont ajoutés. Dans l'environnement Linux, la valeur de eax est utilisée comme valeur de retour de la fonction.
``` leave
ret ```
```leave```Libère la pile.```enter```C'est une instruction associée à.``` ret ```Ensuite, il retourne à l'adresse de l'appelant de la fonction poussé dans la pile par l'instruction d'appel.
# À la fin
Vous pouvez maintenant appeler l'assembly à partir de c. Cette méthode permet au compilateur d'effectuer manuellement des optimisations difficiles à faire automatiquement.
**Happy Hacking!!**
# Les références
* "System V Application Binary Interface AMD64 Architecture Processor Supplement"
http://x86-64.org/documentation/abi.pdf
* th0x4c Remarque: [GDB] Vérifiez la convention d'appel de Linux X86-64 avec Gdb
http://th0x4c.github.io/blog/2013/04/10/gdb-calling-convention/
* Guide to Assembly Language Programming in Linux
http://www.amazon.co.jp/Guide-Assembly-Language-Programming-Linux/dp/0387258973
↓ ↓ Tous les commentaires seront encourageants ↓ ↓
Recommended Posts