Makine diline merhaba (5)
4. MAKİNE DİLİ — | PROGRAMLARIN GİRİLMESİ
Yazı dizimizi buraya kadar takip etmiş olanlarınız için bir özetleme yapalım. Dizimiz şimdiye kadar üç ünite işledi. Bunların ilki ikincisi “*6510 Ana İşlem Ünitesinin Tanıtımı”', üçüncüsü “6510 Ana İşlem Ünitesinin Komutları ve Adresleme Tipleri” idi. Üçüncü bölümün sonunda artık ana işlem ünitemizi tanıyoruz ve bunun tüm komutlarını ve fonksiyonlarını gördük. Be artık bir şeyler yapmanın zamanı geldi değil mi?.. Bu dördüncü bölümde sizlere, makine dili programlarının nasıl girilip yürütüleceğini göstereceğiz. Aslında, programı doğru yöntemle girip çalıştırmak, programı yazabilmek kadar önemli. Diyelim ki, kısa bir program parçası deneyeceksiniz; böyle durumlarda monitor programını kullanmak ideal bir çözüm. Tam aksi durumu gözden geçirelim. Diyelim ki, çok uzun ve ciddi bir program yazacaksınız ve hattâ bu programı profesyonel amaçlarınıza uygun olarak yazacaksınız. Böyle bir durumda monitor programı kullanıp, bu sorunun altından kalkmak, insanoğlu denilen varlığın sınırlarını aşan bir olay. Kısacası, daha işin başlarındayken ipin ucunu kaçırırsanız; ipin ucunu yakalamak için ısrar ederseniz bu sefer de aklınızı kaçırma tehlikesi baş göste- Tir. O yüzden bu bölümü çok dikkatli okuyun ve uygulamaya çalışın. Bu bölümde, size sistemli çalışabilmeniz için bazı öneriler getirmeye çalışacağız. Bunlar, fazla detaylı ve yolu uzatan metotlar olarak görünebilir. Siz kendinize uygun değişiklikleri yapmakta serbestsiniz. Fakat, sizden ricamız buradaki önerilerimizi kulak ardı etmemeniz. Bir önceki bölümde gördüğümüz gibi, makine dili programlar, emir kodlarından ve bunlara ait operandlardan oluşmuş bir bilgi yığınıdır. Yapılan bir işlemi daha yakından takip etmek için, dilerseniz önce BASIC'- te ufak bir örnek program yazalım. Bu programın yapacağı işlem, ekran hafızasına doğrudan bir şey yazmak ve renk hafızasında da bu karakterin rengini koymak olsun. Pek açık olarak görüldüğü gibi bu işlem için BA-SIC'teki POKE komutunu kullanacağız.
POKE 1024, 1: REM “A'nın ekran
POKE 55296,7: REM Sarı renk kodu
Bu komutları verdiğimiz anda, ekranın sol üst köşesinde sarı renkli bir “A” harfi belirir. Şimdi, aynı işlemi makine dilinde nasıl yapacağımızı düşünelim. Hemen, hafızamızı tarak POKE komutunun makine dilindeki karşılığının “STA” olduğunu hatırlarız. Hatırlayacağımız üzere STA komutu, akümülatörün içeriğini belirtilen adrese saklıyordu. Fakat, önce akümülatöre gerekli değeri yüklemek gerekiyordu. Yani:
LDA |
STA 1024
Burada, aküye “1” değerini yükleyip, bunu da 1024 adresli hafıza bitiminde sakladık. Aynı kalıplara sadık kalarak, renk kodunu da oturtabiliriz:
LDA #7
STA 55296
Eğer, bu komutları doğrudan bu şekilde verirsek, sadece “?SYNTAX ERROR” elde ederiz. Bunun nedeni ise Commodore 64'ün direkt olarak sadece BASIC komutlarının anlamasıdır. Yani şu anda izlediğimiz yol yanlış olsa gerek. Hangi yolu izleyelim peki?.. Hatırlayacak olursak, makine dili programlar hafızada peşpeşe dizilmiş emir kodlarından ibaretti. Önce, her bir komutun emir kodunu belirleyelim. Bu işlem için, küçük kitapçığımızı kullanacağız. Buradan, LDA komutunun direkt adresleme tipi için SA9 kodunun kullanılacağını görürüz. Bunun hemen arkasından operand byte'ı gelir. Yani $01. STA komutunda ise absolut adresleme tipini kullanmışız. Küçük kitapçığımız kullanacağımız kodun $8D olacağını söylüyor. Bunun da arkasından, kendisine ait operand gelmek zorunda. Şimdi ise operand, bir hafıza elemanının adresi. Yani 16 bitlik bir değer. Bu değeri temsil etmek için, iki adet 8 bitlik değere ayırmamız gerekiyor. İlk önce düşük değerli byte, arkasından yüksek değerli byte takip etmek zorunda. Onaltı bitlik bir değeri iki adet sekiz bitlik değere ayırma işlemi hekzadesimal sayı sistemi kullanıldığında çok daha rahat yapılabiliyor. O yüzden ilk önce onaltı bitlik değerleri hekzadesimale çevirelim. 1024 sayısı hekzadesimal olarak $0400'a karşılık geliyor. 55296 sayısının karşılığı ise $D800. Programımızı bir kere daha, bu sefer hekzadesimal sayı sistemini kullanarak yazahm.
STA $0400
LDA At $07
STA $D800
Onaltı bitlik değerlerimizden ilki olan $0400'ın düşük değerli byte'ının $00, yüksek değerli byte'ının $04 olduğunu görüyoruz. Yani STA $0400 satırı, byte karşılıkları kullanılarak yazıldığında $8D, $00, $04 byte'ları dizisi olduğunu çıkardık. Benzeri bir analizle, programın geri kalan kısmının, yani LDA 4 $07, STA $D800 kısmını S$A9, $07, $8D, $00, $D8 byte'larıyla temsil edebiliyormuşuz. Tüm programımız şu şekil almıştır:
$A9, $01, $8D, $00, $04, SA9, $07,
$8D, $00,. $D8
Elde ettiğimiz bu byte dizisini hafızaya yerleştirmemiz gerekiyor. Şimdi bir problemle karşılaşıyoruz. Makine dili programımızı hafızanın neresine koyacağız? Bunun için en uygun yer olarak, $C0O00'dan $CFFF'e kadar uzanan bölge göze çarpıyor. Bu bölgenin en önemli özelliği, işletim sistemi ve BASIC yorumlayıcısı tarafından hiçbir zaman kullanılmaması. Bu bölgenin genişliğinin 4 KByte olduğunu görüyoruz. Oldukça avantajlı bir bölge burası. Fakat, büyük ihtimalle, bu bölgede bir monitor programı çalıştırmak isteyeceksiniz ve monitor programı için ise en ideal bölge burası. O yüzden, ilk başlangıç programımız için daha değişik bir yer önereceğim. Burası, işletim sisteminin ve BASIC yorumlayıcısının erişebileceği bir bölge olmasına karşın, diğer programlarınızla çakışma ihtimali daha az. Ayrıca, bu bölgenin BASIC yorumlayıcısı tarafından bozulması ihtimali de çok uzak. Bunun için oldukça uzun bir BASIC programının oldukça çok işlem yapması gerekiyor ki bu bölgeye erişsin ve programınızı bozsun. Şu anda yazmakta olduğumuz ilk deneme prog- Tamımızda herhalde böyle bir durum sözkonusu olmayacağı için gönlümüz rahat etsin! Şimdi, hekzadesimal modda, baştan aşağı yazdığımız programımızı desimale (ondalığa) çevirelim ki BASIC'ten bu kodları rahatça girebilelim. Çünkü BASIC yorumlayıcımız, sadece ondalık sayıları anlıyor ve bunlarla işlem yapıyor.
169,1,141,0,4,169,7,141,0,216
Şimdi ufak bir BASIC programının bu programı bizi için hafızaya yerleştirmesini isteyelim:
100 FOR 1-0TO9
110 READ A:POKE 6*4096 4 1,A
120 NEXT
130 DATA 169,1,141,0,4,169,7,
141,0,216
Bu programı yazıp RUN komutuyla başlattığımızda, makine dilindeki programımız 6*4096 (—$6000-
21
24576) adresinden itibaren belleğe yerleşir. Eh artık makine dilindeki programımızı başlatabiliriz. Bunnun için BASIC'teki SYS komutunu kullanacağız. Şimdi SYS komutunu verip, başlangıç adresi olarak da 6*4096 verirsek makine dilindeki programımız, BASIC yorumlayıcısı tarafından bir alt program olarak çağıracak ve BASIC yorumlayıcısına geri dönmesi beklenecektir. Aman! Dikkat! Az kaldı bir şey unutuyorduk! Diyelim ki ana işlem ünitesi STA $D800 komutunu da yürüttü. Daha sonra ne yapacak? Valla, bu durumda belli değil. Çünkü, bizim yerleştirdiğimiz küçük makine dili programının arkasında neyin yeraldığını bilmiyoruz. Büyük ihtimalle, bu bölgede gelişi güzel içeriğe sahip düzensiz byte değerleri bulunacaktır ve bunların arasında, ana işlem ünitemizi *crash' ettirecek komut kodları da şans esiri bulunabilir. Böyle bir durumda, bilgisayarı, kapatıp açmak veya RESET'lemekten başka çareniz yok. Tabif ki bu olay, ilk makine dili programımızı yazarken pek hoş olmayan bir tecrübe Ana işlem ünitesi dört adet komutumuzu yürüttükten sonra, kontrolü BASIC yorumlayıcısına geçirmelidir. Çünkü, SYS komutu bizim makine dili programını bir altprogram olarak çağırmıştı. Altprogramın geri dönmesi için programımızın sonuna bir adet RTS (return from subroutine) komutu, yani $60 (— 96) kodu eklememiz gerekiyor.
POKE 6*4096 * 10,96
Böylece, programımızın sonuna (10'uncu byte'i olarak) RTS komutunu ekledik. Artık programımızı
SYS 6*4096
komutuyla başlatabiliriz! Derhal, ekranın üst sol köşesinde sarı renkli “A” harfi belirir ve bilgisayar tekrar 'READY.” mesajı vererek BASIC yorumlayıcısına kontrolu verir. Eğer, ekranın sol üst köşesindeki sarı “A” harfini bir türlü çıkaramıyorsanız, komutlarınızı hep ekranın en alt satırından veriyorsunuz demektir. Yani sizin sarı “A” sol üst köşede beliriyor, fakat bilgisayarın kendi mesajları (READY, gibi) yüzünden ekran birkaç satır yukarı kaydırılıyor. Böylece, siz kendi yarattığınız sarı *A” harfini bir türlü göremiyorsunuz. Bu yüzden, komutlarınızı ekranın en alt satırından vermeyin ki ekran kaymasın. Şimdi, aklınıza şöyle bir soru gelebilir: Şu ufacık işlemi yapmak için bu kadar uzun uğraşmak mı gerekiyor? Çünkü burada yapılan işlemlerin çoğu, kodların aranması, operandların belirlenmesi ve sayı sistemlerinin çevrimi. Aslında, görüldüğü gibi, bunların tümü rutin ve belirlenmiş işler. Ee peki, bu işlemleri bil; sayarın kendisi yapamaz mı? Yoksa, bilgisayarın görevi ne? Yani, sonuç olarak öyle bir yardımcı programa ihtiyacımız var ki, *LDA 1” gibi bir makine dili komutunu alsın ve tüm ara işlemleri kendiliğinden yapıp, sonuçta meydana çıkacak kodları otomatik olarak hafızaya yazacak. Gerçekte, bu işi yapan programlar mevcut ve bunlara *ASSEMBLER” adı veriliyor. MART 87 sayımızda TUNA ERTEMALP arkadaşımızın verdiği SUPER AS-SEMBLER (nam-ı diğer HYPRA-ASS) programı bu sınıf programlara kusursuz bir örnek oluşturuyor. Daha ilk baştan, assembler kullanmak yerine, amacımıza adım adım yol almayı daha uygun buluyorum. O yüzden önce monitor programından başlayalım. *Monitor” kelimesi, İngilizcede *izlemek”, fiilinin karşılığıdır. Bu programın yaptığı işlem ise, bilgisayarın ana işlem ünitesinin registerlerini ve belleği yürüyen programla paralel olarak izlememize olanak veriyor. Tabif, bu arada müdahale ederek gerek ana işlem ünitesinin registerleri ni gerekse hafıza birimlerinin içeri lerini değiştirmek mümkün. Makine dili programları, monitor programından başlatmak da olası. Ayrıca, hafızanın bilumum acayip yerlerinde yeralan verilerinizi veya makine dili programlarınızı saklamak veya yüklemek istediğinizde, bu işi en rahat yapabileceğiniz yardımcı programdır monitor. Diyelim ki makine dilindeki programınız tüm hatlarıyla meydana çıktı, (içindeki adresler ve referanslar) böyle bir durumda programınızı monitorun line assembler'ı yardımıyla girebilirsiniz. Onaltılık sistemdeki verileri de belleğe doğrudan yazabilirsiniz. Bu son kullanılan yöntemle birçok programın üzerindeki ufak değişiklikleri yapmanız oldukça kolay ve kısa zamanda gerçekleşen bir olay haline geliyor. Diassembler denilen kullanım sayesinde hafızada yeralan bir makine dili programının listesini almak mümkün. Yazıcınız varsa, bu listing'i kâğıda da dökebilirsiniz. OCAK 87 sayımızda, sözünü ettiğim işlemleri yapan bir monitor programı, kullanımıyla birlikte vermiştim. Yakın bir zamanda, SMON adlı başka bir monitor programı daha vereceğim. Bunlar, yardımıyla birçok programı inceleyebilir, değiştirebilir ve yürütebilirsiniz. Gerçekten de, makine dilini en iyi öğrenme, başkalarının programlarını incelemekle gerçekleşir.