Standardmäßig benutzt der FreeBSD-Kernel die 	C-Aufrufkonvention. Weiterhin wird,
obwohl auf den Kernel 	durch int 80h zugegriffen
	wird, angenommen, dass das Programm eine Funktion aufruft, die 	int 80h verwendet, anstatt 	int
80h direkt 	aufzurufen.
Diese Konvention ist sehr praktisch und der Microsoft®-Konvention von MS-DOS® überlegen. Warum? Weil es die UNIX®-Konvention jedem Programm, egal in welcher Sprache es geschrieben ist, erlaubt auf den Kernel zuzugreifen.
Ein Assembler-Programm kann das ebenfalls. Beispielsweise könnten wir eine Datei öffnen:
kernel: int 80h ; Call kernel ret open: push dword mode push dword flags push dword path mov eax, 5 call kernel add esp, byte 12 ret
Das ist ein sehr sauberer und portabler Programmierstil. Wenn Sie das Programm auf ein anderes UNIX portieren, das einen anderen Interrupt oder eie andere Art der Parameterübergabe verwendet, müssen sie nur die Prozedur kernel ändern.
Aber Assembler-Programmierer lieben es Taktzyklen zu 	schinden. Das obige Beispiel
benötigt eine call/ret-Kombination. Das können 	wir
entfernen, indem wir einen weiteren Parameter mit 	push
übergeben:
open: push dword mode push dword flags push dword path mov eax, 5 push eax ; Or any other dword int 80h add esp, byte 16
Die Konstante 5, die wir in EAX ablegen, identifiziert die 	Kernel-Funktion, die wir
aufrufen. In diesem Fall ist das 	open.
FreeBSD ist ein extrem flexibles System. Es bietet noch andere Wege, um den Kernel aufzurufen. Damit diese funktionieren muss allerdings die Linux-Emulation installiert sein.
Linux ist ein UNIX-artiges System. Allerdings verwendet
	dessen Kernel die gleiche Systemaufruf-Konvention, bei der 	Parameter in
Registern abgelegt werden, wie 	MS-DOS. Genau wie bei der 	UNIX-Konvention wird die Nummer der Funktion in EAX abgelegt. Allerdings werden die 	Parameter nicht auf den
Stack gelegt, sondern in die Register 	EBX, ECX, EDX, ESI, EDI,
	EBP:
open: mov eax, 5 mov ebx, path mov ecx, flags mov edx, mode int 80h
Diese Konvention hat einen großen Nachteil 	gegenüber der von UNIX, was die 	Assembler-Programmierung angeht: Jedesmal,
wenn Sie einen 	Kernel-Aufruf machen, müssen Sie die Register pushen und sie später popen. Das
macht Ihren Code 	unförmiger und langsamer. Dennoch lässt FreeBSD 	ihnen die
Wahl.
Wenn Sie sich für die Linux-Konvention entscheiden, müssen Sie es das System wissen lassen. Nachdem ihr Programm übersetzt und gebunden wurde, müssen Sie die ausführbare Datei kennzeichnen:
% brandelf -t Linux filename
Wenn Sie speziell für FreeBSD programmieren, sollten Sie die UNIX-Konvention verwenden: Diese ist schneller, Sie können globale Variablen in Registern ablegen, Sie müssen die ausführbare Datei nicht kennzeichnen und Sie erzwingen nicht die Installation der Linux-Emulation auf dem Zielsystem.
Wenn Sie portablen Programmcode erzeugen wollen, der auch unter Linux funktioniert, wollen Sie den FreeBSD-Nutzern vielleicht dennoch den effizientesten Programmcode bieten, der möglich ist. Ich werde Ihnen zeigen, wie Sie das erreichen können, nachdem ich die Grundlagen erklärt habe.
Um dem Kernel mitzuteilen welchen Dienst Sie aufrufen, 	legen Sie dessen Nummer in
EAX ab. Natürlich müssen 	Sie dazu wissen welche Nummer
die Richtige ist.
Die Nummer der Funktionen sind in der Datei syscalls aufgeführt. Mittels locate syscalls finden Sie diese in verschiedenen Formaten, die alle auf die gleiche Weise aus syscalls.master erzeugt werden.
Die Master-Datei für die UNIX-Standard-Aufrufkonvention finden sie unter /usr/src/sys/kern/syscalls.master. Falls Sie die andere Konvention, die im Linux-Emulations-Modus implementiert ist, verwenden möchten, lesen Sie bitte /usr/src/sys/i386/linux/syscalls.master.
Anmerkung: FreeBSD und Linux unterscheiden sich nicht nur in den Aufrufkonventionen, sie haben teilweise auch verschiedene Nummern für die gleiche Funktion.
syscalls.master beschreibt, wie der Aufruf gemacht werden muss:
0	STD	NOHIDE	{ int nosys(void); } syscall nosys_args int
1	STD	NOHIDE	{ void exit(int rval); } exit rexit_args void
2	STD	POSIX	{ int fork(void); }
3	STD	POSIX	{ ssize_t read(int fd, void *buf, size_t nbyte); }
4	STD	POSIX	{ ssize_t write(int fd, const void *buf, size_t nbyte); }
5	STD	POSIX	{ int open(char *path, int flags, int mode); }
6	STD	POSIX	{ int close(int fd); }
etc...
In der ersten Spalte steht die Nummer, die in EAX
abgelegt werden muss.
Die Spalte ganz rechts sagt uns welche Parameter wir 	 pushen müssen. Die 	 Reihenfolge ist dabei von rechts nach 	 links.
| Zurück | Zum Anfang | Weiter | 
| Die Werkzeuge | Nach oben | Rückgabewerte | 
Wenn Sie Fragen zu FreeBSD haben, schicken Sie eine E-Mail an
<de-bsd-questions@de.FreeBSD.org>.
Wenn Sie Fragen zu dieser Dokumentation haben, schicken Sie eine E-Mail an <de-bsd-translators@de.FreeBSD.org>.