Makine Diline Merhaba (7)
5. ASSEMBLER
Assembler programı, makine dilinde yazacağımız programları, BASIC'te yazıyormuş rahatlığıyla girmemizi sağlar. Aynen, BASIC'teki gibi satırları listeler, ekranda değiştirebilir, satır ekleyip çıkarabiliriz. Her bir satırın kendisine ait satır numarası vardır. Bu numaranın arkasından assembler komutları gelir. Daha doğrusu, bir satır sırasıyla, satır numarası, bir eksi “ işareti, bir etiket 'LABEL', komut ve operandını, daha sonra da o satıra ait açıklamaları (noktalı virgülle ayrılmış olarak) içerir. Tuna'nın, Süper Assembler'de de bahsettiği gibi bu açıklama kısmını kullanmayı ihmal etmeyin. Yoksa, birkaç ay sonra kendi programınızdan bir şey anlayamazsınız. Burada kullanılan açıklamalar, üretilen kodu hiçbir türlü etkilemiyor ve sadece dökümantasyon amaçlarıyla kullanılıyor. Şimdi bir örnek satır görelim:
100 -TEXT LDA $70,X;
BAŞLANGIÇ DEĞERİNİ ALMAK
Şu anda yazmakta olduğunuz programa, “source” veya kaynak programı denir. Bu programları diğer programlardan kolayca ayırt edebilmek için isimlerinin sonlarına eklemenizi tavsiye ederiz. Assembler'ın, bu kaynak programından ürettiği obje kodunun isminin sonuna da “.OBJ” eklerseniz, çok genel bir konvansiyona uymuş olursunuz. Diyelim ki kaynak programınızı tümüyle yazdınız. Şimdi, RUN komutunu kullanarak assembler programının, obje kodunu üretmesini sağlayın. Kaynak programınız içinde hiçbir şey belirtmediyseniz, obje kodu bellekte üretilecektir. Eğer komutunu kullandıysanız, obje kodunuz sadece disket sürücüsüne belirttiğiniz ad altında gidecektir. Obje kodu üretilirken istenirse bir de assembler listing'i alınabilir. Bu listing, istenirse ekrana, istenirse bir dosyaya, istenirse yazıcıya çıkarılabilir. Eğer tüm “assembly” işlemi hatasız olarak biterse, assembler üretilen obje kodunun ilk ve son byte'larının adreslerini ve tüm işlemin ne kadar zaman sürdüğünü anlatan mesajlar verir. Arkasından “READY.” mesajı ile direkt moda çıkarsınız. Şimdi isterseniz, bir de sembol tablosunu görebilirsiniz. Bunun için veya komutlarını kullanabilirsiniz. Dilerseniz, sembol tablosunun, üretilen assembler listing'inin arkasından otomatik olarak listelenmesini sağlayabilirsiniz. Bir önceki bölümde gördüğümüz, karakter setini ekranda çıkaran örnek bizi oldukça yormuştu. Bunun nedeni ise gereksiz yere uğraştıran hesaplama ve sayı sistemi çevirme işlemleriydi. Şimdi aynı programı, bir de assembler kullanarak yazalım. Bu arada, yeni bir olayla karşılaşacağız. Söz konusu olay yani etiket kullanımı. Tuna'nın Süper Assembler yazısını okuyanlara tanıdık gelecek bu terim bizi birçok sıkıcı işlemden kurtarıyor. Etiketler, program içindeki bazı yerlerin adresini assembler programına hesaplatmamızı sağlıyor. Diyelim ki, biz programımızı sabit adresler kullanarak yazdık. Araya bir bölge ekleyeceğimiz zaman programın birçok bölümü ileri veya geri kayacak ve sonuç olarak adresi değişecek, biz ise programın kendi içinde bu adresleri kullanan bütün bölgeleri bulup elden değiştirmek zorunda kalacağız. Fakat, adresleri önemli yerlerin başına birer etiket koyup, programın diğer kısımlarından buraya yapılacak başvuruların bir etiket üzerinden yapılmasını sağlarsak programımız artık her türlü değişikliğe karşı genel bir yapıya sahip olacaktır ve bizi daha az uğraştıracaktır. Tabii, yukarıda söz ettiğimiz değişikliklere, program içinde başvurulan bir yerin tümüyle silinmesi dahil değil! Sembol ve etiketleri de kullanarak yazacağımız kaynak programımız şöyle görünecektir:
10 - .BA $6000
100 - LDX #0
110 - ETİKET TXA
120 - STA $0400,X
130 -
140 - STA $D900,X
150 - INX
160 - BNE ETİKET
170 - RTS
Ne kadar rahat değil mi? Kullanacağımız bir adrese bir isim veriyoruz ve o adresi artık ismiyle anıyoruz. Assembler, programı iki kerede gözden geçirir (Two pass assembler — İki geçişli assembler). İlk geçişte, tüm etiketleri bulur ve bunlara ait adresleri (o sıradaki program sayacının değeri) belirler ve bunları aklında tutar. Daha sonraki ikinci geçişinde ise etiket ve sembol tablosundan tüm sembolize edilmiş değerleri alır ve obje kodunu üretirken kullanır. Yani, böylece bir programın içinde ilerdeki bir etiketi de kullanmak mümkündür. Buna örnek olarak ufak bir program parçası verelim. Bu kısmın yaptığı işlem onaltı bitlik bir göstergecin değerini bir artırmak olsun:
230 -
INC GÖSTERGEÇ
240 - BNE ATLA
250 - INC
GÖSTERGEÇ * |
260 - ATLA
Burada 240'ıncı satırda daha henüz değeri bilinmeyen ve değeri ancak 260'ıncı satırın işlenmesinden sonra belli olacak bir etiketin veya sembolün değerini kullanabiliyoruz. Tabii, bunu yapabilmemizin sebebi, demin bahsettiğimiz “iki geçiş' olayı. Zaten, assembler ve compiler'lar (derleyiciler) minimum iki geçişli olarak tasarlanırlar. Baştan beri, sözünü ettiğimiz sistemli çalışmaya bir örnek daha verip bu bölümü bitirmek istiyorum. Çünkü, Tuna'nın MART 87 sayısındaki yazısı, birçok detayı açıklıyor. Bunlara burada bir kere daha değinmeyeceğim. Deminden beri etiketten ayrı olarak sembol diye bir şeylerden söz edip durduk. Bunlar gene etiket gibi, assembler'in kullandığı kendine has değişken tiplerinden biri. Biz burada sembolleri, programımızın kaynak kodunu iyice serbest hale getirmek için kullanacağız. Ayrıca kaynak kodumuzun okunabilirliği de önemli ölçüde artacak. Yapacağımız tek işlem, ekran ve renk hafızalarının başı olan sabit sayıyı bir değişkene alıp öyle kullanmak. İşte örneğimiz:
10 -.BA $6000
80 EKRAN—0400
90 EÇ RENK- D800
100 - LDX# 0
110 - ETİKET TXA
120 - STA EKRAN,X
130 - LDA#I
140 - STA RENK,X
150 - INX
160 - BNE ETİKET
170 - RTS
Assembly işlemi bittikten sonra /!! komutlarıyla alfabetik olarak sort edil-
miş sembol listesini istediğimizde şununla karşılaşırız
EKRAN
ETİKET $6002
RENK > $D800
Amaçladığımız şekilde kaynak programımızın okunurluğu ve ilk bakışta anlaşılırlığı büyük ölçüde artmıştır. Artık ekran veya renk ile ilgili adresler kaynak programının birer parametresidir. Diyelim ki ekran hafızasını $2000'a aldınız, (Bunun nasıl yapılacağını, Tuna Ertemalp arkadaşımızın “COMMODORE 64 ile yazısından öğrenebilirsiniz.) karakter setini ekrana çıkarmak için yazacağınız makine dili programının genel görünüşü olduğu gibi yukarıdakiyle aynıdır. Tek yapacağınız:
80
satırı yerine;
80 EKRAN$2000
satırını koymanız. Tabii, büyük ihtimalle programınız normalde bu kadar kısa olmayacak ve her sembol birden çok yerde kullanılacak. Böyle bir durumda ise, sembol kullanmanın avantajları daha iyi anlaşılacak. Pratikte, sembol tablosu en çok sistem değişkenlerini ve sistemde yeralan altprogramları adlarıyla çağırabilmeniz için kullanılıyor. Buna en iyi örnek olarak işletim sisteminin KERNAL tablosunu verebiliriz. Bu tabloda, işletim sisteminden talep edebileceğiniz birçok işlemin (dosya açma, kapama, dosya yükleme, saklama, kullanıcıdan bilgi girişi veya çıkışı gibi) adları ve ROM'da hangi adresten çağırabileceği belirtilmiştir. İleride, sırası gelince bu tabloya da değineceğiz. Sonuç olarak vurgulamak istediğimiz şey, makine dili program yazarken sistemli çalışma prensibini hiçbir zaman elden bırakmamanız. Assembler kullanımı ile ilgili anlatılması gereken birkaç olay daha var. Mesela makro'lar, rekursif makro'lar, pasudo-op'lar, düşük değerli ve yüksek değerli byte'ların assembler'a hesaplattırılması (<, > operandları) vs. Fakat, Tuna arkadaşımız, verdiği Süper-Assembler adlı yazıda, bütün bunları oldukça detaylı bir şekilde açıklamış ve anlatmış. Ben bunları burada bir kere daha tekrarlama gereksinimi duymuyorum. Yazımızın, bir sonraki bölümünde beraberce ufak bir grafik yardımcı programını tasarlayıp gerçekleştireceğiz. Bu işlemi yaparken de, yeni programlama tekniklerini deneyip assembler'ımızı kullanacağız. Şimdilik hoşçakalın... O
NOT:
2 BASK Commodore 64 -
GENE