X86 Assembler unter Linux (Verknüpfung mit C)

Über diesen Artikel

Es gibt zwei Möglichkeiten, mit dem Assembler zu programmieren. Eine besteht darin, das gesamte Programm mit dem Assembler zu erstellen, und die andere darin, nur einige Funktionen mit dem Assembler zu schreiben. Ersteres ist angesichts der geringen Lesbarkeit des Assemblers nicht realistisch. Deshalb wird letzteres zum Mainstream. Durch Schreiben einiger Funktionen in Assembler und anderer in C können sowohl Wartbarkeit als auch hohe effektive Geschwindigkeit erreicht werden.

Notwendige Werkzeuge

Dieser Artikel setzt eine Linux-Umgebung voraus. Der Assembler ist stark von der Umgebung abhängig und funktioniert nur unter Linux. Bitte bereiten Sie die folgende Software in der Linux-Umgebung vor.

Programm erstellen

Schreiben Sie das C-Programm main.c unten und das Assembler-Programm add.asm mit einem Editor und speichern Sie sie.

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

Kompilieren Sie main.c, um eine Objektdatei zu generieren.

gcc -c -o main.o main.c


 Kompilieren Sie add.asm, um eine Objektdatei zu generieren.

#### **` nasm -g -f elf64 -o add.o add.asm `**

Verknüpfen Sie die generierte Objektdatei.

gcc -o add -lc -g main.o add.o -o add


 Jetzt müssen Sie die ausführbare Datei hinzufügen.
 Wenn du rennst
``` 3 ```
 Wird auf dem Bildschirm angezeigt.

# C programmseitiger Kommentar
 Ich werde die Quelle von C erklären. Sehr einfacher Code. Zunächst wird die Funktion `` `int add (int a, int b)` `in extern deklariert.
 In Assembly-Dateien können Header-Dateien keine Verbindungen zwischen Objekten verarbeiten, wie Sie es normalerweise in C tun würden. Deklarieren Sie es daher mit extern und geben Sie den externen Link an.
 Die anderen Teile sind die gleichen wie bei einem normalen C-Programm.
 Ebenso können Sie in C ++ vom Assembler erstellte Funktionen aufrufen.

# Assembler-Nebenkommentar
 Da es sich um einen Funktionscode handelt, wird er Zeile für Zeile erklärt.

#### **` section .Text Bedeutet den Anfang des Codes..Neben Text.data(Deklaration der initialisierten Daten)、.bss(Deklaration nicht initialisierter Daten)Es gibt einen Abschnitt von, der jedoch in diesem Code weggelassen wird.`**

global _asm_addMarker_asm_Add wird global angegeben, damit auf andere Codes verwiesen werden kann.

Ist ein Marker. Darunter befindet sich die Funktion asm_Der Körper von add.



``` enter 0,0 ```Ist eine Anweisung zum Erstellen eines Stapelrahmens. Ein Stapelrahmen ist ein Speicherziel für Daten, die im Speicher erweitert werden. Es speichert die in der Funktion verwendeten Variablen und die Adresse des Befehls, der nach Beendigung der Funktion zurückgegeben werden soll.

mov eax, edi mov ebx, esi

 Verschiebt die Argumente a und b in das Allzweckregister. In der Linux-Umgebung werden Funktionsargumente in Registern gespeichert und übergeben. Dies dient dazu, die Häufigkeit des Zugriffs auf den Speicher zu verringern und den Prozess zu beschleunigen. Es gibt eine Eins-zu-Eins-Entscheidung, welches Register die Daten enthält, von denen das Argument der Funktion gespeichert ist. Die Entsprechungstabelle ist unten dargestellt.

 |registrieren|Streit|
 |:-------:|:------:|
 | edi |Erstes Argument|
 | esi |Zweites Argument|
 | edx |Drittes Argument|
 | ecx |Viertes Argument|
 | r8d |Fünftes Argument|
 | r9d |Sechstes Argument|

 Ab dem 7. Argument wird es über den Stapel ausgetauscht. In Anbetracht der Ausführungsgeschwindigkeit und Lesbarkeit benötigen Sie jedoch wahrscheinlich nicht mehr als das 7. Argument.

add eax, ebx

 Der Inhalt von ebx und der Inhalt von eax werden hinzugefügt. In der Linux-Umgebung wird der Wert von eax als Rückgabewert der Funktion verwendet.
``` leave
ret ```
```leave```Gibt den Stapel frei.```enter```Es ist eine Anweisung gepaart mit.``` ret ```Dann kehrt es zu der Adresse des Funktionsaufrufers zurück, der von der Aufrufanweisung auf den Stapel geschoben wurde.

# Am Ende
 Sie können die Assembly jetzt von c aus aufrufen. Mit dieser Methode kann der Compiler manuell Optimierungen durchführen, die nur schwer automatisch durchzuführen sind.
**Happy Hacking!!**

# Verweise
* "System V Application Binary Interface AMD64 Architecture Processor Supplement"   
    http://x86-64.org/documentation/abi.pdf
 * th0x4c Hinweis: [GDB] Überprüfen Sie die Aufrufkonvention von Linux X86-64 mit 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

 ↓ ↓ Kommentare sind ermutigend ↓ ↓









Recommended Posts

X86 Assembler unter Linux (Verknüpfung mit C)
[C] [Python] Lesen mit AquesTalk unter Linux
Verwenden von X11 mit ubuntu18.04 (C-Sprache)
Richten Sie Docker unter Oracle Linux (7.x) mit Vagrant ein
Testen Sie Python mit Miniconda unter OS X und Linux mit travis-ci
PIL mit Python 3.x unter macOS installieren
Führen Sie Linux mit ARM-Architektur mit QEMU aus
Kompilieren des Linux-Kernels (Linux 5.x unter Ubuntu 20.04)
Kommunizieren Sie mit I2C-Geräten unter Linux C.
Inu x Memo
Richten Sie golang mit goenv unter GNU / Linux ein
[Hinweis] Installieren Sie wxPython 3.x unter Linux Mint (Ubuntu)
Starten Sie einen Prozess mit einer Planungsrichtlinie unter Linux
Fügen Sie Python 2.7.x in pyenv unter Mac OSX 10.15.5 ein
Erstellen Sie Oracle Database 19c unter Oracle Linux 8.3 (zweiter Teil der DB-Konstruktion)
Installieren Sie PHP der 7er-Serie unter Amazon Linux 2 mit Amazon Linux Extras
Verwendung von C216 Audio Controller unter Arch Linux
Yum-Befehl zum Zugriff auf MySQL mit Python 3 unter Linux
So installieren Sie caffe unter OS X mit Macports
Machen Sie mit Python einen Haltepunkt auf der c-Ebene
Erstellen Sie kompakt eine Oracle-Datenbank (19c) unter Linux auf VirtualBox
Installieren Sie PyQt5 mit Homebrew unter Mac OS X Marvericks (10.9.2).
Einfache Erstellung von C ++ - Code mit CMake auf Docker
Prozesse unter Linux dämonisieren
Behälterartig hergestellt mit C # 1
C / C ++ - Debugging mit gdb
jblas unter Arch Linux
Linux Kernel Release 5.x (2/4)
Linux (WSL) unter Windows
NAT-Router unter Linux
Linux (Lubuntu) mit OneMix3S
Linux Kernel Release 5.x (3/4)
Entwickeln Sie .NET unter Linux
Wake on Lan unter Linux
Überwachen Sie den Datenverkehr unter Linux
Aktualisieren Sie vscode unter Linux
Linux Kernel Release 5.x (4/4)
Linux Kernel Release 5.x (1/4)
Erstellen Sie LiveUSB unter Linux
Linux-Betrieb unter Win10
Probleme mit Chrome nach dem Anhalten auf dem Linux-Desktop KDE + Nvidia
Intuitive Passwortverwaltung mit aws ssm unter Mac / Linux-Alias
USB-Geräteprogrammierung mit nativem C unter Android 5.0 und höher
BASIC und C sowie Assembler-Geschwindigkeitsvergleich und -optimierung spielen mit IchigoJam
Lernen Sie "x86-Architektur mit Ihrem eigenen Emulator" mit Manjaro (Linux)
Erstellen Sie Python3 für Windows 10 unter ARM mit Visual Studio 2019 (x86) unter Windows 10 unter ARM
So installieren Sie Theano unter Mac OS X mit Homebrew
Rufen Sie den Hostnamen des Host-PCs mit Docker unter Linux ab