Bu sayfadaki yazılar
Sayfanın metni
Sayfa 34
Merhaba Assembler'cılar. Geçen sayıda, 68000'in komutlarına başlayıp; taşıma işlemi yapan MOVE komutunu görmüştük. Bu sayıda ise MOVEQ komutunu, adres registerlerine atama yapan LEA ve bir register veya hafıza adresindeki sayıyı başka bir sayı ile toplayan ADD komutunu parametreleriyle birlikte göreceğiz. Bunların yanısıra diğer aritmetik işlemleri yapan SUB (çıkarma işlemi), MULU (Çarpma işlemi), DIVU (bölme işlemi) ve registerler arası veri alışverişi yapmayı sağlayan EXG komutlarını da inceleyeceğiz.
MOVE komutunun çalışmasını daha iyi anlamanız için C-MONITOR'de size eğlenceli bir örnek verelim. İlk önce C-MONITOR'u yüklemeniz gerekecek. Eğer yüklemeyi başardıysanız CLI window'un en sonunda C-MONITOR ile ilgili başlık yazıları ve bir noktanın yanında kursorumuz belirecektir. Şimdi RETURN tuşuna basarak MONITOR'un tüm komut listesine şöyle kısaca bir göz atın. Bu komutlar, C-MONITOR'de noktadan sonra yazılarak çalıştırılırlar. Daha sonra sırası geldikçe bu komutların hepsini öğreneceğiz.
Şimdi noktadan sonra şunları yazın ve RETURN tuşuna basın.
.n 50000 RETURN'e basar basmaz alt satırda şunlar belirecektir.
050000: Kursor şimdi iki noktanın yanındadır. Kursordan itibaren yazmaya devam ediyoruz.
050000: MOVE.B * 252, SBFE00l (RETURN tuşu)
050000: RTS (RETURN tuşu) 05000A: (RETURN tuşu) Son satırda hiçbir komut yazmadan doğrudan RETURN tuşuna bastık. Nedeni, n 50000 ile girdiğimiz Assembler Edit modundan çıkmak içindir.
Şimdi noktanın yanında olan kursorun oraya şunları yazın.
.G 50000 (RETURN tuşu) Burada RETURN tuşuna bastığınızda, bütün satırları doğru yazdıysanız görünürde hiçbir değişiklik olmayacaktır. Fakat Amiga'nızın kırmızı POWER LED'ine baktığımızda sönmüş veya biraz kararmış olduğunu görürüz. LED'in sönmeyip kararması, daha çok yeni 1.3 versiyonlarda gözlenebilir. Version 1.2 ve bazı 1.3 KICKSTART'larda LED tamamen kararacaktır.
Şimdi ve olayın nasıl olduğuna, yani yukarıdaki iki satırın daha doğrusu bir satırın (MOVE.B #252,$BFE001) AMIGA'mızın POWER LED'ini nasıl söndürdüğüne göz atalım.
AMIGA'nın ROM'undaki $BFE001 no'lu adresin 1'inci BIT'i AMIGA POWER LED'in açık veya kapalı olmasına karar verir. Yani bu Bit 1 olunca LED On (Açık), 0 olunca LED Off (Kapalı) durumundadır.
Biz ilk satırdaki MOVE komutunu işleme sokmadan önce bu adreste ($BFE001) 252 sayısı vardı. Yani birinci bit 1 idi. MOVE komutu işleme girince adresteki birinci bit 0 oldu (254). Ve LED buna bağlı olarak söndü.
$BFE001 = %11111100 = 252 (ilk hali)
$BFE001 = %11111110 = 254 (Move komutundan sonraki hali)
1. birinci bit değişiyor. Amiga hafıza adreslerinde bit'lerin sıralanışı şöyle olmaktadır (Adreste 252 değeri olduğunda): Değer = 1111110 0 Bit Numarası = 7 6 5 4 3 2 1 0
Bit'ler soldan sağa doğru 0'dan itibaren sıralanırlar, örnekte değeri 0 olan ilk bit'in numarası da 0'dır. İkinci bit'in numarası 1, 3'üncünün değeri 2 ve böylece devam eder.
Amiga'nızın ROM belleğinde bunun gibi daha birçok bit çok büyük işler görmektedir.
MOVEQ KOMUTU
Bu komuta MOVE komutunun hızlandırılmışı diyebiliriz. Fakat MOVEQ komutunun yüksek hızı, ona bazı kısıtlamalar getirir.
İlk olarak işlem yaptığı modlar, sade-
AMIGA ASSEMBLER
ce BYTE modundaki sayılar olmak zorundadır. Yani 0'dan 255'e kadar olan sayıları taşıyabilmektedir. Aslında taşıma kelimesi yanlış oluyor. Çünkü sadece Data Registerleri ile çalışmaktadır. MOVEQ komutu ile ne bir adresten sayı alabilir, ne de başka bir yere koplayayabilirsiniz. Sadece herhangi bir data registerine bir sayı, daha doğrusu BYTE uzunluğunda (0-255) arası bir sayı gönderebilirsiniz. Tabii çok yüksek bir hızda çalışmaktadır. MOVE komutunun aynı işlemi bir defa yapana kadar, MO-VEQ komutu 3 defa tekrarlayabiliyor. MOVEQ komutunun bunlar dışında bir kısıtlaması daha vardır. Komut ile atama yaptığınızda, yapılan işlem data registerinin tümüne hitap eder. Yani MOVEQ * 17,D0 dediğinizde D0 registerindeki değer tamamen (32 bit olarak) silinir ve yerine 17 değeri gelir. Tabii MOVE komutundan 3 kat hızlı olarak. D0 = 00000017 Oysa MOVE.B komutu ile aynı örneği tekrarladığımızda; MOVE.B ** 17,D0, komutu data registerinin sadece ilk bayt'- ına etki eder. Örneğin komut işleme girmeden önce D0'da 40602303 değeri bulunsun. Komut işleme girdikten sonra; D0 = 40602317 olur.
Bu iki farkın programlamada yerine göre çok büyük yararlarını göreceksiniz.
MOVEM KOMUTU
Bu komut yardımı ile Adres ve Data registerlerinin değerlerini, hafızada istediğimiz yere gönderip tekrar lazım oluncaya kadar orada saklayabiliriz. Ve istediğimiz zaman onları yine MOVEM komutu ile çağırıp kullanabiliriz.
Bu komutun Amiga'da işlevi büyüktür. Bir sürü programın çalışması esnasında, registerlerin değerlerinin taşınması ve birbirlerine karışmaması için kullanılmaktadır.
Formatı ise şu şekildedir. MOVEM register numaraları, saklanacakları adres
Register numaraları olarak, saklamak istediğimiz adres ve data registerlerini kullanabiliriz. Register numaralarını ister tek tek, ister kombine olarak kullanabiliriz.
örnek olarak; D4 Yalnız D4'ü gönder D4-D6 D4,D5,D6'yı gönder D2-D3/A0-A3 D2,D3,A0,Al,A2,A3'ü gönder
D0/A3 D0 ve A3'ü gönder örneklerde görüldüğü gibi Adres ve Data registerleri bölme işareti ile (/) birbirlerinden ayrılıyorlar. Eksi işaretini (- ) kullanarak da aynı gruptan birkaç register i birden ifade etmiş oluyoruz.
Saklanacak adres olarak, ister herhangi bir adres yazarız. İstersek Stack Pointer'a atarız. Tabii SP (Stack Pointer)'e göndermek daha seri ve zahmetsiz olur. Nedeni ise onları tekrar SP'den alana dek gözden uzak bir bölgede bizi beklerler. Şimdi MOVEM komutunun modlarını açıklayıcı birkaç örnek verelim.
Klavyeyle gezinmek için ← ve → tuşları.
Sayfa 35
1. Kullanım Modu : MOVEM.L D0- D1/A4-A5, (A0)
D0,D1 ve A4,A5 registerlerinin içerikleri (AO)'in gösterdiği adrese saklanacak.
2. Kullanım Modu : MOVEM.L D0/A2-A3, $40000
D0 ve A2.A3 registerleri $40000'den itibaren LONGWORD olarak yerleşecekler.
3. Kullanım Modu : MOVEM.L D0- D7/A0-A6,-(SP)
DO'dan D7'ye kadar ve AO'dan A6'ya kadar olan registerler (kısaca bütün registerler) Stack Pointer'in gösterdiği adresin arkasına yerleşecekler.
Artık registerleri istediğimiz yerlere saklamayı öğrendik. Şimdi onları tekrar kullanılmak üzere okumayı görelim.
4. Kullanım Modu: MOVEM.L (SP) + ,D0-D7/A0-A6
Stack Pointer'in gösterdiği adresteki LONGWORD'ları sırası ile D0'dan D7'ye ve AO'dan A6'ya kadar olan registerlere (kısaca bütün registerlere) gönder.
Bu komut akıllıca bir kullanım sayesinde beni çok büyük dertlerden kurtardı. Ayrı ayrı iki tane programdan alınmış ve bir arada kullanılacak iki rutin düşünün. Ve programın akışı sırasında bu iki rutine tekrar tekrar erişmeniz gereksin. Bu iş kolay. Fakat iki rutin de aynı registerleri kullanıyorlarsa ve birinci döngüden sonra registerlerdeki sayılar ikinci döngü için bir anlam ifade ediyorsa program çalışmayacaktır. Şimdi MOVEM komutunun zamanı gelmiştir. Hemen rutinlerin başına ve sonuna MOVEM komutlarını ekleyerek probleminizi çözebiliriz.
Bunlara ek olarak, MOVEM komutuna her programımızda ihtiyaç duyacağız. Programlarımıza başlamadan önce MOVEM komutu yardımı ile bütün registerleri Stack Pointer'e atacak ve programlarımızdan çıkarken onları SP (Stack Pointer)'den tekrar okuyup, registerlere yazacağız.
LEA KOMUTU Orijinal adı (LOAD EFFECTIVE ADDRESS) olan bu komutun yaptığı iş, herhangi bir adres registerine bir adresi atamak.
Aslında bu komutun yaptığı işi MOVE komutu da yapıyor. Fakat LEA kadar hızlı olmuyor. LEA komutunun görevi adresleri taşımak olduğundan sadece LONGWORD olarak çalışıyor.
Örnekler; 1. Kullanım Modu : LEA $50000,A0 $50000 adresi değerini A0 adres registerine gönder.
2. Kullanım Modu : LEA (A0),A2 (A0) registerinin içeriği olan adresi, A2 adres registerine gönder. 3. Kullanım Modu : LEA 4(A0),A2 Bu örneğin yukarıdakinden değişikliği A0 adres registerinin içeriğine artı 4 eklenerek çıkan sonucun A2 adres registerine gönderilmesidir. Yani diyelim ki (A0)'da $50000 var ve yukarıdaki komut icra oldu. Sonuçta $50000'e başındaki pozitif sayı yüzünden 4 eklenir ve ortaya çıkan $50004 değeri A2 adres registerine gönderilir.
Başlangıçta MOVEA.L #$50000, A0 komutu ile LEA $50000, A0 komutu arasında hiçbir fark gözükmese de zamanla konuda ilerlediğinizde aradaki büyük farkı göreceksiniz.
Bu arada MOVE.L #$50000, A0 ile MOVEA.L #$50000, A0 arasında hiçbir fark yoktur. MOVE'dan sonraki A harfi, değerin bir adres registerine atanacağını belirler.
Aynı şekilde MOVE.L #14,D0 ile MOVE.L #14,D0 arasında da hiçbir fark yoktur. Biz bu A ve I harflerini yazmasak da Monitör programları (C MONİTÖR ve SEKA ASSEMBLER) onları bizim kullanımımıza göre düzenleyeceklerdir.
ADD KOMUTU Add komutu bir hafıza adresindeki veya bir adres veya data registerlerindeki değerlerin üzerlerine yeni bir değer eklemek için kullanılır. Bu işleme toplama adını veriyoruz. Çalışması gayet basittir. Byte, Word, Longword olarak çalışabilmektedir. Yani ADD komutunun Longword modu ile 0'dan $FFFFFFFF'e kadar olan sayıları rahatlıkla toplayabileceğiz. Kullanım modları şöyledir.
1. Kullanım Modu: ADD.L #10,D0 veya ADDI.L #10,D0
D0 data registerindeki değere 10 daha ekliyoruz. Toplama sonucu ortaya çıkan değer yine D0 registerine yazılmaktadır.
2. Kullanım Modu : ADD.L #255,A0 veya ADDA.L #255,A0
A0 adres registerindeki adresin değeri 255 artırılmış oluyor. 3. Kullanım Modu : ADD.B #$18, $50000
$50000 nolu hafıza adresindeki değeri $18 artırmış oluyoruz. Fakat $50000 adresinde $F0 değeri varsa ve $F0 + $10 işlemini BYTE olarak toplarsak sonuçta $50000'de 00 değeri alır. Çünkü toplamada bir BYTE'ın alacağı değerleri geçmiş bulunuyoruz. Bu yüzden komut sadece bir Byte'a sığabilecek kısmını $50000'e yazacak. Ve bilgisayar EXTEND ve CARRY Flagları ile bizi, toplama işleminde taşma olduğuna dair uyaracaktır.
4. Kullanım Modu : ADD.L D0,D1 Bu komut ile, D0 data registerindeki LONGWORD değeri D1 registerindeki değere eklenmesini ifade ediyoruz. Komutu aynı şekilde LONGWORD yerine