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.
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.
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_add
Marker_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