Amiga Dünyası sayı 26, sayfa 18

Bu sayfadaki yazılar

Sayfanın metni

Sayfa 18

komutları mevcut. Buradaki tanımlamalar listemiz içerisinde bulunmayan _printf ve .begin rutinlerinin programımızın içerisine ekleneceğini belirtiyor. Bu ekleme olayı link sırasında gerçekleşiyor. Buradan da anlaşılacağı gibi program aslında ilk olarak .begin alt rutinine ve daha sonra _main rutinine sıçrıyor. '.begin' rutinini inceleyerek neler yaptığını görebilirsiniz. Rutinlerin assembler listesini Aztec disketlerinde bulabilirsiniz.

Şimdi yukarıdaki 'public' deyiminden yararlanarak bir assembler alt rutine daha göz atalım;

/* Aztec-C Assembler */ /* alt rutinlerinin */ /* kullanimi; */ /* Örnek 3. */

main()

{ printf("Sol tuşa basiniz!..\n"); while(!mouse()); printf("\n");

}

#asm

public _mouse _mouse:

clr.l d0 btst #6,$bfe001 bne.s lm add.I #l,d0 lm: rts

#endasm

artık burada rutin tanımlamamızı direkt olarak assembler listesi içerisinden yapıyoruz, 'public' komutunu kullanmadığımız takdirde C listesi içerisinden mouse() rutinini çağıramayız. Sonuç olarak 'public' assembler komutu, yanında verilen ismin diğer programlar tarafından bir rutin olarak tanımlanmasında kullanılıyor.

Assembler listeleri aynı zamanda C'de kullanılan değişkenleri de tanıyabiliyor ve ulaşabiliyor. Bunu bir örnekle inceleyelim;

/* Aztec-C Assembler */ /* altTutinlerinin */ /* kullanimi; */ /* Örnek 4. */

long a;

main()

{ move(); printf("a=%d\n",a);

)

#asm

public _move _move:

move.l #10,_a rts

#endasm

'a' değişkenini global olarak tanımlıyoruz. Bu sayede kendi hazırladığımız '_move' assembler rutini, değişkeni tanıyabiliyor. Burada '_a'ya 10 değerini verdiğimizde, C'den de bu değeri okumamız mümkün. Bu yöntemle ortak olarak assembler ve C dilleri arasında değişken kullanmak mümkün olabiliyor. Programımızın assembler listesini incelediğimizde '_a' değişkeni için 4 byte'lık bir yer ayrıldığını görebiliyoruz. Listemizi bir inceleyelim;

;:ts=8 ;/* Aztec-C Assembler */ ;/* alt rutinlerinin */ ;/* kullanimi; */ ;/*Omek4. */

;int a;

global _a,4

;main() ;{

public _main _main:

link a5,#.2 movem.l .3,-(sp) ;move();

jsr _move ;printf("a=%d\n",a);

move.l _a,-(sp) pea .1+0 jsr _printf

add.w #8,sp ;} .4

movem.l (sp)+,.3 unlk a5 rts .2 equ 0 •3 reg .1

dc.b97,61,37,100,10,0 ds 0

;#asm

public _move _move:

move.l #10,_a rts

public _printf public _move public .begin dseg end

'global' assembler komutu ile '_a' değişkeni için 4 byte'lık yer ayrılıyor. Bu satırın başında dikkat ettiyseniz '; int a;' mevcut. Hatırlarsanız 'int' tipindeki bir değişken normalde 2 byte'lık yer harcaması gerekirken, burada 4 byte'lık yer ayrılmış. Bunun sebebi compile ederken;

CC +L -t prog.c içerisinde +L opsiyonunu kullanmamız. Bu sayede bütün 'int' tipindeki değişkenler 'long' tipine çevriliyor ve 4 byte'lık yer harcıyor. Programı bir de;

CC -t prog.c

olarak compile edin. Bu durumda '_a' değişkeni için 2 byte'lık yer harcandığını görebilirsiniz. Fakat bu durumda programın çalışması tehlikeye biniyor. Çünkü hazırlanan assembler alt rutinler genellikle parametrelerini 'long' türünde istediğinden, bu şekilde değişkenleri yollamak daha sağlıklı.

Bu ayki programlarımız da bu kadar. Bu yazımızda, Amiga C içerisinde assembler rutinlerini kullanmayı öğrendik. Assembler rutinleri yazarken çok dikkatli olun. Bildiğiniz gibi assembler hata affetmez. Gelecek ay yeni örnek programlarla buluşmak üzere hepinize iyi günler...

Klavyeyle gezinmek için ← ve → tuşları.