Bu sayfadaki yazılar
Sayfanın metni
Sayfa 23
ASLA Akü $47 içersin 001000111 9010001110 $8E, C-0
Bu örneğimizde sonuç olarak akümülatör'ün içeriği olarak $8E elde ettik ve Carry bit'i (flag'ı) söndürüldü, çünkü kaydırmadan önce akümülatör'ün 7'nci bit'i “0” içeriyordu. Akümülatör'ün kaydırmadan önce ve sonraki içeriklerini karşılaştırırsak görürüz ki akümülatör'ün içeriği iki katına çıkmış. Durumu daha iyi kavrayabilmek için ondalık sistemde düşünelim. Şayet ondalık bir sayıyı bir basamak sola kaydırırsak değeri on katına çıkar. Aynı olayın ikili sistem için de geçerli olduğunu gözönünde bulundurursak, demin elde ettiğimiz sonucun rastlantı olmadığını görürüz. Yani ASL komutu ile bir sayıyı iki katına çıkarabiliriz. Bir örnek daha inceleyelim.
ASL A Akü $CD içersin $CD %011001101 %110011010 $9A, C=1
Carry flag'ını işlemin sonucunda sol taraftaki ekstra bit olarak görürsek, gene sayımızın değerinin iki katına çıktığı sonucuna varırız. $CD (205)'in iki katı $19A (410)'dur.
#
5 e te |
LSR
LSR komutu “logical shift right”-ın kısaltılmışı olup, ASL komutunun tersi işlemi yapar. Burada byte'ın içeriği sağ tarafa kaydırılır. 7'nci bit'e “0” yüklenir. Dışarı çıkan 0'ncı bit ise Carry'e alınır. Bir örnekle görelim:
LSR A Akü $CA içersin $CA %011001010 %001100101 = $65, C=0
Sonuç olarak akümülatör'de $65 ve sönük bir Carry bit'i elde ettik. Sizin de dikkatinizi çektiği gibi akümülatör'ün değeri yarıya indi. Carry bit'i kaydırmadan önceki sıfırıncı bit'in kopyasını içeriyor, başka bir deyişle Carry bit'i ikiye bölme sırasında artan olup olmadığını gösteriyor. Böylece bir sayının tek mi, çift mi olduğunu belirleyebiliriz. LSR en alttaki bit'i Carry'ye çıkarır, böylece BCC ve BCS komutları ile dolaylı olarak en alttaki bit'i test edebiliriz. Eğer LSR komutu bir hafıza elemanını adreslerse akümülatör'ün içeriği değişmez.
ROL
ROL komutu “rotate left'in kısaltılmışından gelir ve bit'lerin içeriğini ise dizilmiş boncukları kaydırır gibi döndürür. Sola kaydırma sırasında boşalan sıfırıncı bit'in yerine Carry bit'i kopya edilir. Dışarı çıkan yedinci bit'in içeriği ise Carry bit'ine alınır. Daha genel bakarsak, yapılan işlem dokuz bit'lik bir bilginin kendi içinde döndürülmesidir (Byte'a ait 8 bit ve Carry bit'i). Bir örnek daha iyi kavramımızı sağlayacak: ROL A Akü $4B içersin Carry yanık olsun $4B %001001011 C=1 %010010111 $97
Bütün bit'ler bir basamak sola kaydı. Carry bit'i boşalan sıfırıncı bit'in yerine geldi. Dışarı çıkan yedinci bit Carry'ye alındı. Sonuç olarak $97 ve sönük bir Carry elde ettik. Burada da akünün değerinin iki katına çıktığını, fakat bundan başka mesela daha evvel oluşmuş bir eldenin veya daha evvelki bir kaydırma işleminden çıkmış Carry bit'inin de toplandığını görüyoruz. Bu son yorum oldukça ilgi çekici, çünkü Carry bit'i yalnızca toplama ve çıkarmada değil, aynı zamanda sağa ve sola kaydırmalarda birkaç byte'ı birbirine bağlamak için kullanılan bir ara değer taşıyıcısı durumunda bulunuyor.
ROR
ROR komutu (rotate) ROL komutunun tam tersi işlemi yapar. Bu sefer bit'lerin dönüş yönü sağa doğrudur. Bir örnekle görelim: ROR A F Akü $89 içersin Carry sönük olsun $89: %10001001 C=0 %01000100 C=1
Akümülatör'ün içeriği olarak $89'dan $44 elde ettik. Carry'nin yanık olması bölme işleminde artan olduğunu gösteriyor. Kaydırma komutlarında Carry Flag'ından başka sonuca göre N- ve Z-flag'ları da etkilenir. Aşağıdaki tabloda komutları ve adresleme tiplerini bulacaksınız.
Adresleme tipi ASL LSR ROL ROR akü $0A $4A $2A $6A absolut $0E $4E $2E $6E
0.cı sayfa $06 $46 $26 $66 absolut X-indeksli 0.cı sayfa X-indeks $16 $56 $36 $76
$1E $5E $3E $7E
Klavyeyle gezinmek için ← ve → tuşları.
Sayfa 22
Şimdi hafıza ve register'leri bir eksilten komutları görelim.
DEX
Bu komut X-register'inin içeriğini bir eksiltir. Sonuca göre N- ve Z-flag'ları etkilenir. Diyelim ki X-register'inin içeriği $00'dı ve biz eksilttik. Bu durumda $FF elde ederiz ve hiçbir şekilde Carry flag'ı etkilenmez. BASIC'te aynı işi yapan satır şöyle olacaktır.
X-X-I
Tabii negatif sayı diye bir şey söz konusu olmayacaktır.
DEY
Bu komut Y-register'inin içeriğini bir eksiltir. DEX komutu için söylenenler aynen geçerlidir. BASIC'te aynı işi yapan satır:
Y=Y-1 Burada da $00'dan $FF'e geçeriz. DEC
Bu komut belli bir adresteki hafıza biriminin içeriğini bir eksiltmeye yarar. Bu işlem sırasında akümülatör'ün içeriği kesinlikle etkilenmez. INC komutu için söylenenler aynen geçerlidir. Aşağıda komutları, adresleme tiplerini ve komut kodlarını bulacaksınız.
Komut Komut kodu
INX $E8 INY $C8 DEX $CA DEY $88 Adresleme tipi INC DEC absolut $EE $CE absolut X-indeksli $FE $DE 0. sayfa X-indeks $F6 $D6 10. Flag'ları Değiştirme Komutları
Flag'ların durumuna göre programın akışını değiştiren komutlardan başka, kullanıcının flag'ları istediği biçimde değiştirmesini sağlayan komutlar da mevcuttur. Daha evvel de örneklerini gördüğümüz gibi; toplama ve çıkarma işlemlerinden önce bu tip komutları kullanıp C-flag'ının durumu belirlenmelidir. Bu gruptaki komutlar operand'a ihtiyaç göstermezler ve bir Byte'a sığarlar.
Carry flag'ı
SEC (“set carry”) komutu ile C-flag'ı yakılır. CLC (“clear carry”) komutu ile de C-flag'ı söndürülür. SEC komutu her çıkartma işleminden önce, CLC komutu ise her toplama işleminden önce kullanılmalıdır, yoksa yanlış sonuçlar elde ederiz. Tabii birkaç byte genişliğindeki bilgileri toplayıp, çıkarıyorsak ara işlemlerde C-flag'ı ile oynamayın, çünkü C-flag'ı, byte'ların birbirine birleşmesi sırasında gerekli bilgileri içerir. Carry flag'ı yalnızca ilk toplama veya çıkarma işleminden önce belirlenmelidir.
Decimal flag'ı
Bu flag toplama ve çıkarma işlemlerinin bildiğimiz ikili sistemde mi, yoksa ikili kodlanmış ondalık sistemde mi (Binary Coded Decimals, BCD) yapılacağını belirler. BCD modunda işlem yapabilmek için C-flag'ının yanık olması gerekir. Konuya yeterince hakim olmadıkça bu modu kullanmanızı pek tavsiye etmeyiz. Daha ileride yayınlayacağımız “PROGRAMLAMA TEKNİKLERİ” bölümünde, bu modun detaylarını açıklayıp örnek bir program geliştireceğiz. O zamana kadar sabır!.. D-flag'ını yakmak için SED (“set decimal”) komutunu, bu flag'ı söndürmek için ise CLD (“clear decimal”) komutunu kullanacağız.
Interrupt flag'ı
Interrupt denilen olay, programın yürürken, herhangi bir (hardware) donanımın gönderdiği sinyal yüzünden kesilmesi, özel bir program parçasının yürütülmesi, daha sonra da kesilmiş olan programa hiçbir şey yokmuş gibi olduğu gibi geri dönmesidir. Aslında yukarıdaki uzun cümle olayın çok basit bir özetidir. Daha ileride bu olaya çok daha detaylı olarak eğileceğiz. Interrupt flag'ı interrupt'a izin verilip verilmediğini belirler. I-flag'ını yakmak için SEI (“set interrupt disable”) komutunu kullanırız ve durum da interrupt'a izin verilmez. Interrupt'a tekrar izin vermek için I-flag'ı söndürülmelidir. Bunun için CLI (“clear interrupt disable”) komutu kullanılır.
Overflow flag'ı
Overflow flag'ı sadece söndürülebiliyor (Çünkü yakmanın pek bir anlamı yok). Bu işi yapan komut ise CLV (clear overflow). COMMODORE 64'ümüzün ana işlem ünitesi 6510'da bulunmayan, fakat 6502 ana işlem ünitesinde bulunan bir özellikten bahsedelim. Bu flag aynı zamanda ana işlem ünitesinin bir bacağına uygulanan bir sinyal tarafından da yakılabiliyor. Yani programdan bağımsız da etkilenebiliyor bu flag. Tekrar yakılabilmesi için söndürülmesi gerektiğinde CLV komutu kullanılıyor. Bilhassa 1541 Disk-Drive'de çok kullanılan bu özelliğe yazımızın ilerleyen bölümleriyle değineceğiz. Aşağıdaki tabloda komutları ve komut kodlarını bulacaksınız.
Komut Komut kodu CLC $18 SEC $38 CLD $D8 SED $F8 CLI $58 SEI $78 CLV $B8
11. Bit Kaydırma Komutları
6510 ana işlem ünitemizin yürüttüğü başka bir komut grubu daha var ki, bu gruptaki komutlara karşılık gelen BASIC komutları yok, bu grup bit kaydırma komutlarını içeriyor. Sözkonusu işlem sırasında akümülatör'ün, ya da adreslenen hafıza biriminin bit yapısı bir bit sağa veya sola kaydırılır. Şayet kaydırılan şey akümülatör ise, akü adreslemesinden söz ediyoruz. Bu gruptaki komutlar adresleme tipine göre bir, iki, ya da üç byte uzunluğunda olabiliyor. Şayet adresleme tipi bir hafıza elemanını gösteriyorsa, aynen INC ve DEC komutlarındaki oku-değiştir-yaz (Read-Modify-Write) işlemleriyle komut yürütülür. Bu işlem sırasında akümülatör'ün içeriği korunacaktır.
ASL
ASL, anlam olarak “arithmetic shift left'in baş harflerinden oluşmuş bir kısaltmadır. Yapılan işlem şudur: Adreslenen byte'ın içeriği bir bit'lik pozisyon olarak sola kaydırılır. Sıfırıncı bit'in yeri boş kalacağı için oraya “0” yazılır. Yedinci bit'teki bilgi ise dışarda kalır. O da Carry'ye alınır. Diyelim ki akü ile bu işi yaptık. Bir örnekle görelim: