ASSEMBLER - 3
Makine dili kursumuzun geçen ayki bölümünde INX ve DEX komutlarını kullanarak bir döngünün nasıl yapıldığını, bu ay ise 8 ve 16 Bit hesap işlemlerini daha detaylı olarak ele alacağız. Bu işlemler oldukça farklı bir mantığa dayandığı için ilk başta öğrenilmesi zor ve sıkıcı gelebilir. Yalnız şunu unutmayın ki, bu tür işlemler Assembler'da program yazarken çok sık kullanılır. Bir müddet sonra bunların görüldüğü kadar karışık olmadığını anlayacaksınız. Şimdi kaldığımız yerden dediğimiz gibi X ve Y registerleri 0 ile 255 arası değerler alabilmekteydi, zira en büyük 8 Bit sayı 255'tir. $FF (desimal 255) (1) 0000 0000 (desimal 256)
Bu işlemde de görüldüğü gibi 255'ten sonra kullanılan bayt sıfır değerini alır, çünkü 9. Bit devreye girmiştir. Bilgisayarın bu durumda ne yaptığını görmek için aşağıdaki işlemleri
1500 LDA & Ol
1502 BRK
satırını girdiğimizde tüm registerlerin o anki durumu ekrana gelir. AC XR YR N V — BD 01 00 00 0 1 1 0
01 değeri yer almaktadır. Şimdi X = $FF (- 255) değerini verelim. Bunun için programda ufak bir değişiklik yapmamız gerekmektedir.
1500 LDA # $01
1502 LOX # $FF
1504 BRK
ANIL GÜL
Tekrar G1500 yazdığımızda ekranda şu satırlar gözükür:
AC XR YR N V — 01 FF 00 1 0 1 100090 X-Registerinde beklenildiği gibi $FF değeri bulunmaktadır, fakat nedense statü registerindeki N-göstergesi (negatif sayıları gösteren gösterge) de 1 değerini almıştır. Şimdi yine ufak bir değişiklikle X-Registerindeki 255 değerini arttıralım. 1504 INX 1505 BRK
G1500 ile programı çalıştırdığımızda aşağıdaki register gösterimi ile karşılaşırız:
AC XR YR N V — 01 00 0 001 10010 Tahmin ettiğiniz gibi X-Registeri tamamen dolduktan sonra tekrar “0” değerini almıştır. N-göstergesi eski değeri olan sıfırı alırken diğer taraftan Z-göstergesi “1” olmuştur. Eğer bir önceki işlemin sonucu sıfır ise bu gösterge her seferinde “1” değerini alır.
1505 INX
1506 BRK
Yukarıdaki değişikliği yapıp G1500 ile programı çalıştırdığımızda registerler şu şekle girecektir: AC XR YR N V — BD I Z C 01 01 00 0 0 1 10000
Yukarıdaki işlemleri Y-Registeri içinde yaparsak yine aynı sonucu alırız. Yalnız bu registeri kullanırken bazı komutları uygun şekilde değiştirmeliyiz:
21
Assembler dilinde kullanıcının yükünü hafifleten bazı sayı ve işaret belirtme yöntemleri mevcuttur. Bu yöntemlerden biri BCD sayılarıdır. BCD, “binary coded decimal” veya “ikilik sistemde kodlanmış desimal sayı” anlamındadır. Bu yöntemde 0'dan 9'a kadar olan tüm rakamlar ikilik sistemde 4 Bit'lik bir sayı ile kodlanmıştır:
İkil
0000 0001 0010 OO11 0100 0101 1000 1001
Desimal:
1010'dan 1111'e olan sayıların BCD kodları mevcut değildir. Eğer elimizde iki basamaklı bir desimal sayı varsa (örneğin 12) önce bu sayı her basamağındaki rakamlara ayrılır (1 ve 2) ve ikilik olarak kodlanır. Örneğimizdeki 1 rakamının BCD karşılığı 0001 ve 2 rakamının karşılığı ise 0010'dur. Bu ikisi birleştirildiğinde 12 sayısının BCD kodu olan 0001 0010 ortaya çıkar. Her sayı farklı sayıda basamağa sahip olduğu için BCD sistemindeki sayılar için belli bir bayt sayısı söylenemez. Örneğin 1984 sayısı 2 bayt kullanmaktadır ve karşılığı 0001 1001 1000 0100'dür. Yukarıda belirttiğimiz 1010 ile 1111 arası kullanılmayan altı kod yüzünden BCD sayıları ile işlemler zorlaşır.
Burada sadece statü registerindeki desimal göstergesini 1 yapmalıyız. Şimdi iki yeni komut daha öğreneceğiz SED ve CLD. Bunlardan birincisi İngilizce “set decimal-flag” sözcüklerinin kısaltmasıdır ve “desimal göstergesini aç” anlamına gelmektedir. Buna karşılık CLD (clear decimal-flag) ise aynı işlemin tersini yapmaktadır, yani desimal göstergesini kapamaktadır. Eğer bir program yazarken herhangi bir yerde desimal göstergesini açmışsanız, daha sonra yapacağınız ikilik sistem işlemlerinden önce bir hata ile karşılaşmamak için CLD komutunu kullanın! Yukarıdaki iki komut da 1 bayt uzunluğundadır ve ikisinin de ardında herhangi bir adres yer almaz. Bu şekilde BCD kodlama sistemini de öğrendikten sonra ikilik sistemindeki negatif sayılara geçebiliriz. Bu konuyu üç aşamalı olarak ele alacağız. 1) Negatif sayıları belirtmek için özel bir gösterge kullanılır. Bu gösterge 1 değerini aldığında negatif sayıları, 0 değerini aldığında ise pozitif sayıları belirtir ve her baytın 7. Bit'inde yer alır. Örneğin 1 eskisi gibi 0000 0001 iken, -1 şimdi 1000 0001 olur. Fakat bu sistemde 1 bit gösterge olarak kullanıldığı için 1 bayt ile ifade edilebilen sayıların bölgesi 0-255'ten -127'ye kaymıştır. Artık ifade edebildiğimiz en büyük sayı 0111 1111 (+127) olmuştur. Şimdi bu sistemi kullanarak aşağıdaki toplamayı yapalım.
#10 0000 1010
dukça karmaşık bir hal almaktadır. —© — 1900 0N10
Fakat C-64'ün mikroprosesor'ü bu 1001 0000 — -16 sonucunu
sayılarla doğrudan çalışabilmektedir. verir.
0800 00 08 CA 00 41 25 B2
0800 OOOA A Ya -
Sonraki Basic — Satır No.: 10 Komut
satırı |
0808 AB 31 Ba 00 12 08 14 08
— 1 2 Satır 0812 0014
Komut Sonu — Sonraki Basic — Satır No.: 20
satırı |
0810 80 00 00 CÜ FF FF FF FF
END Satır Program Büş
Komut Sonu Sonu
Monitör programı bu şekilde gösterir.
YA
za İML
Görüldüğü gibi +4 sonucunu elde etmemiz gerekirken (-16) değeri ortaya çıkmıştır. Demek ki eksi sayılarla bu şekilde işlem yapamıyoruz. 2) Daha sonraki aşamada sayının birinci dereceden karşılığı hesaplanır. Burada pozitif sayılar için herhangi bir değişiklik söz konusu değildir. Negatif sayılar ise pozitif sayıların Bit'lerinin değerlerinin değiştirilmesiyle elde edilir. Yani 8-Bit bir sayıdaki 0 ve 1'ler yer değiştirirse o sayının negatifi elde edilir. Örneğin 00001100 (+12) ise bunun birinci dereceden karşılığı (-12)'dir. İşin ilginç yanı burada da daha önce öğrendiğimiz 7. Bit'in negatif sayıları belirtme özelliğinin geçerli olmasıdır. Bu şekilde iki gösterim şeklini birleştirmiş olduk, fakat şimdi bu şekilde hesap yapılıp yapılmayacağını incelemeliyiz. (+8) = 0000 1000 (-6) = 1111 1001 (1) 0000 0001 sonucu ortaya çıkar. İşlemin sonucunda bir taşma meydana gelmiştir (9. Bit 1 olmuş) ve yine beklenen değer elde edilmemiştir. Yani eksi sayılarla bu yöntemle de toplama, çıkarma yapamayız. 3) Eğer bir sayının birinci dereceden karşılığına “1” değerini ilave edersek ikinci dereceden karşılığını elde ederiz. Bilgisayarımız negatif sayıları bu son belirttiğimiz yöntemle algılar. Pozitif sayılar herhangi bir değişikliğe uğramaz, örnek olarak (-12) sayısını ele alalım.
(4)— 0000 0100 (Normal ikilik karşılığı) (—12)— 1111 0100 (Birinci dereceden karşılık) 0000 0001
1111 0100 (İkinci dereceden karşılık)
Şimdi isterseniz bu yöntemle bir toplama işlemi yapalım:
(4—6)— 0000 0100 1111 1010 (Bu (4—6)'nın (1) 0000 0001 ikinci dereceden karşılığı yani (—2)'dir) Baş tarafta yer alan 9 Bit'in bir bayta sığmayacağını düşünürsek doğru sonuca ulaştığımızı görürüz. Bu tür işlemlerde eğer negatif bir sonuç ortaya çıkarsa bunun gerçek değerini hesaplamak kolay değildir. Böyle durumlarda ortaya çıkan sayının tekrar ikincil karşılığı hesaplanır ve işareti değiştirilir. (4—15) 0000 0100 1111 0001 (—11) 1111 0101 Yukarıda çıkan sonuç (—11)'in ikinci dereceden karşılığıdır. Kontrol için ikinci dereceden karşılığını hesaplayıp, işaretini ters çevirelim.
Birinci karşılığı
0000 0000 + 1 0000 0001 sonuç 0000 0001
Çıkan sonucun (—1) işaretini değiştirirsek aradığımız (—1) sayısına ulaşırız. İşte bilgisayarımız yukarıda anlattığımız sistemle negatif sayıları hesaplamaktadır, yalnız burada eksik kalan bazı noktalar var. Bunun için yazıp kullandığınız monitör programından çıkıp aşağıdaki Basic satırlarına girin.
10 AX——İ2
28 END
Değişkenler Bellekte Nasıl Duruyor?
Yazdığımız programı daha “RUN” ile çalıştırmayın, şimdi tekrar monitör programına girip biraz önceki Basic satırlarını inceleyelim. Yalnız monitör programını işletmek için “RUN” komutunu kullanamayız, çünkü bu komutu kullandığımızda hafızadaki Basic programımız işleyecektir. Bu nedenle monitör programının başlangıç adresini bilip, o adres için “SYS” komutunu kullanmalıyız. C-64'ün Basic belleği normal durumlarda $0800'dan başlamaktadır. Monitör programındayken M 0800 yazalım. Bizi burada $081C'ye kadar olan baytlar ilgilendirmektedir. Resim de belleğin bu bölümü kısaca yorumlanmıştır. Basic programımız $0813'de son bulur. Bunu arka arkaya gelen iki boş bayt'tan anlıyoruz. Bu adreslerin arkasında programda kullanılan değişkenlerin değerleri yer alır. Yalnız bir daha programımızı “RUN” ile çalıştırmadığımız için bu baytlar “0” değerindedir. “X” ile monitörden çıkıp programı çalıştırırsak $081C'ye kadar olan baytlar değişmeyecek, fakat daha sonraki 7 bayt Resim 2'deki konuma gelecektir. Önce $0814 ve $0815'i ele alalım.
Bu baytlar değişkenin adını ve tipini belirtir. Bilgisayar, burada iki baytın da 7. Bit'i “1” olduğu için tam sayılar kullanılacağını anlar. Kullanılan değişkenin cinsini belirten 7. biti unutursak, $0814'de A harfinin kodu ve $0815'de sadece “0” değeri yer alır. Bildiğiniz gibi C-64 Basic'inde de değişkenler en fazla iki harften oluşabilmektedir. Geri kalan $0816 - $0817 arası baytlar ise tam sayı değişkenlerinde kullanılmaz. $0816'da ikilik sistem karşılığı 1111 0100 olan $F4 yer almaktadır. Bu değer (—12)'nin ikinci dereceden karşılığıdır. Peki $0817'deki $FF ne anlama gelmektedir? Daha önce söylediğimiz gibi tam sayılar hafızada 2 baytta saklanmaktadır. (—12)'nin 16 Bit ile gösterimi şu şekildedir:
Birinci dereceden karşılık
HA 0000 0000 06000 1100 0000 0000 0001 TELİ 0100 —(—12) yüksek bayt alçak bayt —$F4
2 bayt ile gösterilebilen en büyük pozitif sayı (+32767) ve en küçük negatif sayı (—32768)'dir. Şimdilik bu sayı oyunlarına son verebiliriz. Eğer yukarıda anlatılan sistemle biraz işlem yaparsanız birçok sefer doğru sonuç çıkmasına rağmen bazen de yanlış değerlerle karşılaşırsınız. Daha önce yeteri kadar açıklık kazandırmadığımız bir soruyu, şimdi rahatlıkla cevaplayabiliriz: Kullandığımız registerin 7. Bit'i eğer “1” değerini almışsa, statü registerindeki negatif göstergesi kesinlikle “1” olur. Bu aylık da bu kadar! Gelecek ay kaldığımız yerden devam etmek üzere...
Adres : — O8tA 0815 0816 0817 0817 - OBTA
Bayı 1 2 4 5-7
cı 80 FF F4 00 00 00
Değer : 1100 0001 11111111 1111 0100
7 Bitler tamsayı değişkenini | Yüksek — Alçak bayt Boş
belirtir.
6100 0001 165
Anın kodu
Değişken adı ve tipi Değişken değeri Kullanılmamış
Basic programlardaki değişkenler C-64 tarafından böyle düzenlenir.