Assembleur X86 sous Linux (lien avec C)

À propos de cet article

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.

Outils nécessaires

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.

Créer un programme

É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_addMarqueur_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

Assembleur X86 sous Linux (lien avec C)
[C] [python] Lire avec AquesTalk sous Linux
Utilisation de X11 avec ubuntu18.04 (langage C)
Configurer Docker sur Oracle Linux (7.x) avec Vagrant
Tester Python avec Miniconda dans un environnement OS X et Linux avec travis-ci
Installation de PIL avec Python 3.x sur macOS
Exécutez Linux avec l'architecture ARM à l'aide de QEMU
Compilation du noyau Linux (Linux 5.x sur Ubuntu 20.04)
Communiquez avec les périphériques I2C sous Linux C
Inu x Memo
Configurer Golang avec goenv sur GNU / Linux
[Note] Installez wxPython 3.x sur Linux Mint (Ubuntu)
Démarrer un processus avec une politique de planification sous Linux
Mettez Python 2.7.x dans pyenv sur Mac OSX 10.15.5
Construire la base de données Oracle 19c sur Oracle Linux 8.3 (deuxième partie de la construction de la base de données)
Installez PHP série 7 sur Amazon Linux 2 avec Amazon Linux Extras
Comment utiliser le contrôleur audio C216 sur Arch Linux
Commande Yum pour accéder à MySQL avec Python 3 sous Linux
Comment installer Caffe sur OS X avec macports
Faire un point d'arrêt sur la couche c avec python
Construisez de manière compacte une base de données Oracle (19c) sous Linux sur VirtualBox
Installez PyQt5 avec homebrew sur Mac OS X Marvericks (10.9.2)
Construction facile de code C ++ avec CMake sur Docker
Démoniser les processus sous Linux
En forme de conteneur réalisé avec C # 1
Débogage C / C ++ avec gdb
jblas sur Arch Linux
Version du noyau Linux 5.x (2/4)
Linux (WSL) sous Windows
Routeur NAT sur Linux
Linux (Lubuntu) avec OneMix3S
Version du noyau Linux 5.x (3/4)
Développer .NET sur Linux
Wake on LAN sous Linux
Surveiller le trafic sous Linux
Mettre à jour vscode sur Linux
Version du noyau Linux 5.x (4/4)
Version du noyau Linux 5.x (1/4)
Créer LiveUSB sur Linux
Fonctionnement Linux sur Win10
Problèmes avec Chrome après la suspension sur le bureau Linux KDE + Nvidia
Gestion intuitive des mots de passe avec aws ssm sur alias Mac / Linux
Programmation de périphérique USB avec C natif sur Android 5.0 et supérieur
La comparaison et l'optimisation des vitesses BASIC et C et assembleur jouent avec IchigoJam
Apprenez «l'architecture x86 apprise avec votre propre émulateur» avec Manjaro (Linux)
Créer Python3 pour Windows 10 sur ARM avec Visual Studio 2019 (x86) sur Windows 10 sur ARM
Comment installer Theano sur Mac OS X avec homebrew
Obtenez le nom d'hôte du PC hôte avec Docker sous Linux