11.3. Sistem Çağrıları

11.3.1. Geçerli Çağrıdüzeni

FreeBSD çekirdeği varsayılan olarak C çağrısistemini kullanır.Program direk int 80h çağrısıyerine bu çağrıyıyapan dışarıdan bir fonksiyona erişim ile gerçekleştirilir. Bu sistem çok kolaylaştırıcıdır ve MS-DOS sistemlerine göre harikulada bir özelliktir. Çünkü Unix sistemi programıhangi dilde yazılmışolursa olsun çekirdeğe ulaşmaya izin verir.

Aynışekilde bunu assembly dili de gerçekleştirebilir.Mesela sistem çağrılarıile bir dosya açabiliriz.

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

Bu çok taşınılabilir ve temiz bir kodlama biçimi değişik kesmeleri değişik parametre aktarımınıkullanan Unix sistemlerinde kodunuzu aktarmanız için gereken tek şey çekirdek prosedürünü değiştirmektir.Bu prosedür yukarıda kernel etiketi ile belirtilmiş yerdir.

Assembly programcılarıdöngüleri azaltmayıseverler.Yukarıdaki örnek call/ret kombinasyonu gerektirir. Bunu kaldırmak için ekstradan bir word daha eklememiz gerekir.

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

Burada 5 eax içine gönderilerek çekirdek (kernel) çağırıldı. Buda 'open' fonksiyonunu ifade ediyor.

11.3.2. Alternatif çağrıdüzeni

FreeBSD oldukça esnek bir sistemdir. Çekirdeği(Kernel) başka şekillerde çağırmak da mümkündür. Ama bunun çalışmasıiçin Linux emülasyonun yüklü olmasıgerekir.Linux'te yine Unix tarzıbir işletim sistemidir ama çekirdek fonksiyonlarınıçağırırken parametreleri yığından(stack) değil MS-DOS gibi yazmaçlardan yapar.Unix gibi fonksiyon numarasını'eax' yazmacına(register) koyar. Parametreler ise EBX,ECX,EDX,ESI,EDI,EBP yazmaçlarına kaydedilir.

open: mov eax, 5 mov ebx, path mov ecx, flags mov edx, mode int 80h

Bu yöntem Unix yöntemine göre daha verimsiz bir yöntemdir. Zira her sistem çağrısında yazmaçlarıkaydetmek için onlarıyığına yükledikten sonra geri çağırmak için 'pop' fonksiyonu çağrmamız gerekecektir. Bu da programımızıyavaşlatacaktır. Yine de FreeBSD bu olanağısize alternatif olarak veriyor.

Eğer Linux yöntemini seçecekseniz bunu assembler programına bildirmeniz gerekir. Programıderleyip bağladıktan (link) sonra aşağıdaki komutlarıkullanarak çalışabilir hale getirebilirsiniz.

% brandelf -f linux filename

11.3.3. Hangi düzeni kullanmalıyız ?

Eğer özel olarak FreeBSD için programlama yapıyorsanız Unix sistemini kullanmalısınız : Daha hızlıdır global değişkenleri yazmaçlarda saklayabilirsiniz, brand komutunu kullanmak zorunda da değilsiniz.Ayrıca hedeflenen sistem için Linux emülasyon paketine de ihtiyaç duymaz.

Eğer daha taşınabilir bir kod üretmek istiyorsanız o zaman Linux sistemini tercih etmelisiniz .

11.3.4. Çağrınumaraları

Çekirdek , sistem çağrılarınıkullanırken hangi fonksiyonun çağırılacağıEAX yazmacına göre belirlenir.Buraya koyulan numaraya göre işlem gerçekleştirilir.Elbette bunun için hangi numaranın hangi fonksiyona karşılık geldiği bilinmelidir.

11.3.4.1. syscalls dosyaları

syscalls.locate dosyasıiçinde listelenmişdeğişik biçimlerde bulunan numaralar otomatik olarak syscalls.master tarafından üretilmiştir.

Standart Unix çağrıdüzeni için master dosyası /usr/src/sys/kern/syscalls.master dosyasındadır.Linux emülasyon modunda ise /usr/src/sys/i386/linux/syscalls.master dosyasındadır.

Not: FreeBSD ve Unix sistemlerinin düzeninden farklıolmasına ek olarak aynıfonksiyonun numaralarıda farklıolabilir.

syscalls.master çağrıların nasıl gerçekleştirileceğini tarif eder.

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); }
vesaire...

En soldaki değer EAX yazmacına konulacak sayıyı gösterir.

En sağdaki sutun parametreleri belirtir.Bu parametreler stack içine push komutu ile gönderilmelidir.Gönderim işlemi sağdan sola yapılır.

Örnek olarak eğer bir dosya açacaksak 'open' fonksiyonunun numarasıolan 5 sayısınıEAX a koyduktan sonra ilk önce mode argümanınısonra flags argümanınıve en son da path isimli işaretçi değişkenini yığın yapısına göndermemiz gereklidir.