Interaktion mit C
In diesem Kapitel werden wir die Integration von ARM64-Bit-Assembler und C-Programmen beleuchten. Die folgenden Themen werden behandelt:
C-Funktionen aus Assembler aufrufen
Um C-Funktionen aus Assembler heraus aufzurufen, müssen Sie die folgenden Schritte beachten:
- Deklaration der C-Funktion in Assembler
- Aufruf der Funktion
- AAPCS (ARM Architecture Procedure Call Standard) beachten
Beispiel in C:
// myfunctions.c
#include <stdio.h>
void my_function(int x) {
printf("The value is: %d\n", x);
}
Beispiel in Assembler:
.extern my_function // Extern deklarierte Funktion
.global _start
_start:
mov x0, #42 // Parameter für die Funktion (Wert: 42)
bl my_function // Aufruf der C-Funktion
// Exit system call
mov x8, #93 // syscall number for exit
mov x0, #0 // exit code
svc 0
Wichtige Hinweise:
- Die C-Funktion muss mit .extern deklariert werden, um den Linker zu informieren.
- Die Parameter müssen gemäß den AAPCS-Regeln in die entsprechenden Register geladen werden (x0 bis x7).
- Der Rückgabewert der Funktion wird in x0 zurückgegeben.
Assemblerfunktionen in C aufrufen
Wenn Sie Assemblerfunktionen in C aufrufen möchten, müssen Sie sie korrekt definieren und deklarieren, um sicherzustellen, dass der C-Compiler und der Linker sie finden und korrekt aufrufen können.
Beispiel in Assembler:
// myfunctions.s
.global add_numbers
add_numbers:
add x0, x0, x1 // Addiere x0 und x1, Ergebnis in x0
ret // Rückkehr zur aufrufenden Funktion
Beispiel in C:
// main.c
#include <stdio.h>
extern int add_numbers(int a, int b); // Deklaration der Assemblerfunktion
int main() {
int result = add_numbers(5, 7);
printf("Result: %d\n", result);
return 0;
}
Kompilierung und Linken:
gcc -c main.c
as -o myfunctions.o myfunctions.s
gcc -o myprogram main.o myfunctions.o
Wichtige Hinweise:
- Die Assemblerfunktion muss mit .global deklariert werden.
- In der C-Datei muss die Assemblerfunktion als extern deklariert werden.
- Parameter und Rückgabewerte müssen gemäß den AAPCS-Konventionen übergeben werden.
Inline-Assembler in C
Inline-Assembler ermöglicht die Einbettung von Assembler-Code direkt in C-Programme, um bestimmte Leistungsoptimierungen oder spezielle Hardwarezugriffe zu ermöglichen.
Beispiel:
#include <stdio.h>
int add_numbers(int a, int b) {
int result;
__asm__ (
"add %w0, %w1, %w2"
: "=r" (result)
: "r" (a), "r" (b)
);
return result;
}
int main() {
int result = add_numbers(5, 7);
printf("Result: %d\n", result);
return 0;
}
Parameter-Erklärung
- "add %w0, %w1, %w2": Assembler-Befehl. %w0, %w1, %w2 sind Platzhalter für die entsprechenden Register.
- : "=r" (result): Output-Parameter. Das Ergebnis wird in das C-Variable result geschrieben.
- : "r" (a), "r" (b): Input-Parameter. Die C-Variablen a und b werden den entsprechenden Platzhaltern zugeordnet.
Wichtige Hinweise:
- Inline-Assembler ist architekturspezifisch und sollte mit Bedacht verwendet werden.
- Beachten Sie die korrekte Verwendung und Zuordnung der Register.
Bibliotheken verwenden
Um C-Bibliotheken in ARM64-Assembler zu verwenden, müssen Sie sicherstellen, dass die Bibliotheken korrekt eingebunden und die entsprechenden Funktionen extern deklariert werden.
Beispiel: Verwendung der math.h-Bibliothek:
Beispiel in C:
// mymath.c
#include <math.h>
double sqrt_wrapper(double x) {
return sqrt(x);
}
Beispiel in Assembler:
.extern sqrt_wrapper
.global _start
_start:
ldr x0, =9.0 // Lade 9.0 in x0
bl sqrt_wrapper // Rufe sqrt_wrapper auf
// Exit system call
mov x8, #93 // syscall number for exit
mov x0, #0 // exit code
svc 0
Kompilierung und Linken:
gcc -c mymath.c
as -o myprogram.o myprogram.s
gcc -o myprogram myprogram.o mymath.o -lm
Wichtige Hinweise:
Deklarieren Sie alle externen Funktionen, die Sie verwenden möchten. Stellen Sie sicher, dass die Bibliotheken korrekt beim Linken einbezogen werden (-lm beispielsweise für die Math-Bibliothek).