Bu sayfadaki yazılar
Sayfanın metni
Sayfa 37
Örnek: SUB.L #1, $50000 ile yapacağımız çıkarma işlemini SUBQ.L
#1, $50000 ile 2 kat daha hızlı yapabiliriz.
SUBQ komutunun diğer parametrelerini yazmaya gerek görmüyorum. Çünkü yukarıdaki SUB komutu parametreleri ile tamamen aynıdır. Tabii tek fark SUBQ'nun 1'den 8'e kadar sayılarla çalışma kısıtlılığı olmasıdır.
Artık Amiga Assembler'da toplama ve çıkarmayı öğrenmiş durumdayız. Bu iki işlemde problemsiz olarak ve diğer programlama dillerden yüzlerce kat daha hızlı çalışıp, Assembler dilinin verdiği rahatlık ve yüksek hız ile klasımızı konuşturduk.
Şimdi sıra dört işlemden geriye kalan, çarpma ve bölme işlemine geldi. Makine dilinde tabii ki bu işlemlerde bir hayli hızlı şekilde yürütülüyor. Fakat işlemci çarpma ve bölme işlemlerini toplama ve çıkarma işlemleri kadar hızlı yapamıyor. Nedeni ise çarpma ve bölme işlemleri sırasında bu işlemleri toplama çıkarma işlemlerine dönüştürüp, bol bol toplama çıkarma yapıp zaman harcaması oluyor.
MULU KOMUTU Görevi çarpma işlemi olan bu komutun kısıtlaması sadece WORD olarak işlem görmesidir. Gerçi yine de bu, o kadar büyük bir kısıtlama olduğu söylenemez. Çünkü komutun bu haliyle bile $FFFFFFFF x $FFFF sayıları arasında olan çarpma işlemlerini rahatlıkla yapabiliriz. Fakat sekiz haneli hexadecimal sayılar da işinizi görmezse; artık bana, kendi çarpma rutinlerinizi yazmanın zamanı gelmiştir demekten başka bir şey kalmıyor.
Komutun kullanım modları ise aşağıdadır. 1. Kullanım Modu: MULU #$10,D0 D0 data registerindeki sayı $10 ile çarpılır. İşlemin sonucu olan sayı D0'a yazılır.
2. Kullanım Modu: MULU $50000,D0 $50000 hafıza adresindeki sayı ile D0 registerindeki sayı çarpılır. Sonuç D0 registerine yazılır. Burada dikkat edilmesi gereken bir şey vardır. $50000'den alınan sayı her zaman WORD olacaktır. Diğer bir deyişle MULU komutundaki çarpımın ilk sayısı (komut parametresinin ilk hanesi) iki byte'ı geçemez. Bir örnek ile daha iyi açıklayalım: $50000 adresinde sırası ile $01, $00, $45, $00 byte'ları sırası ile dursun. D0 data registerinde de $15 değeri bulunsun. Örnek komutumuz ise şu olsun: MULU $50000,D0
İşlemci bu komut ile şu işlemi yapar. $50000 adresindeki WORD değeri alıp ($0100) D0 registerindeki $15 ile çarpar. $0100 x $15 = $1500
Komuttan sonra ortaya çıkan sonuç ($1500) D0 registerine yazılır.
3. Kullanım Modu: MULU (A0), D0 Duruma göre MULU komutunun ilk parametresine doğrudan direkt hafıza adresi yazmak yerine, adres registeri üzerinden kullanabilirsiniz. Yukarıdaki örnekte olduğu gibi A0 adres registerinin gösterdiği adresin içindeki sayıyı, D0 data registeri ile çarpmasını ifade etmiş oluyoruz.
4. Kullanım modu: MULU 2(A0), D0 Örnekte A0 adres registerinin gösterdiği değere ek olarak 2 sayı daha ekleyip ortaya çıkan yeni adresteki sayıyı, D0 registerindeki sayı ile çarparız.
Yukarıdaki 2(A0)'a daha açıklayıcı olarak; A0 adres registerinde $50000 olduğunu varsayalım, örnekteki gibi bir komutta ise $50000'e 2 daha ekleyerek $50002'deki sayı ifade edilmiş oluyor.
Dikkat ettiyseniz MULU komutunun ikinci parametreleri hep Data registeri olmaktadır. Bu komutta da böyle bir kısıtlama vardır.
DIVU KOMUTU Amiga makine dilinde bölme işlemlerini bu komut ile yapacağız. Bu komut da MULU komutu gibi işlemciyi çok yoran komutlardan bir tanesidir. Her şeyden önce DIVU komutunun WORD adres olarak çalıştığını söyleyebiliriz. Dolayısıyla kapasitesi LONGWORD bir sayıyı WORD bir sayıya bölmek oluyor. Diğer bir anlatımla 32 bit uzunluğunda herhangi bir sayıyı 16 bit uzunluğunda bir sayıya bölebilmektedir. DIVU'nun çalıştığı sayılar ise $FFFFFFFF bölen, $FFFF bölüm olmaktadır. Bu sayılar bir programcı için rahatlıkla her işi görecek kapasitededir.
Bölme işleminin sonucunda sonuç sayısı, kullanılan data registerinin ilk WORD'una ve elde kalan sayı ise ikinci WORD'a yazılmaktadır.
Şimdi DIVU komutunun parametrelerini inceleyelim:
1. Kullanım Modu: DIVU #$10,D0 D0 data registerindeki sayı $10'a bölünür. İşlemin sonucu olan sayı D0'a yazılır. Elde varsa D0 data registerinin ikinci WORD'una yazılır. Başka bir deyişle 16-31 nolu bit'lere yazılır. 2. Kullanım Modu: DIVU $50000,D0 $50000 hafıza adresindeki sayı, D0 registerindeki sayıya bölünür. Sonuç D0 registerine yazılır.
3. Kullanım Modu: DIVU (A0), D0 Duruma göre DIVU komutunun ilk parametresine doğrudan hafıza adresi yazmak yerine adres registeri üzerinden kullanabilirsiniz. Yukarıdaki örnekte olduğu gibi A0 adres registerinin gösterdiği adresin içindeki sayıyı, D0 data registerindeki sayıya bölmesini ifade etmiş oluyoruz.
4. Kullanım Modu: DIVU 2(A0), D0 örnekte A0 adres registerinin gösterdiği değere 2 sayı daha ekleyip ortaya çıkan yeni adresteki sayı, D0 registerindeki sayıya bölünür.
68000 Makine Dilinde DIVU komutuna ek olarak bir de DIVS komutu vardır. İşleyiş olarak aynı olan bu iki komutun tek farkı, DIVS'in eksi (-) işaretli sayıları da bölebilmesidir. DIVU bu gibi durumlarda eksi sayıların işaretlerini dikkate almaz.
DIVU komutu ile beraber makine dilinde dört işlemi görmüş oluyoruz. Dört aritmetik işlem yapan komutlardan sonra, kolay anlaşılır bir komut olan EXG'yi görelim.
EXG EXG'nin yaptığı iş çok basittir. Görevi herhangi iki registerin içeriklerini değiştirmek. Kullanılan registerlerin adres veya data registerleri olması hiçbir şeyi değiştirmez. Komutun işleyişinde registerler tümü ile (LONGWORD olarak ihtiva edildikleri dört byte ile beraber) taşınırlar. BYTE veya WORD olarak Data ve adres registerlerini taşımak bu komut ile mümkün olmuyor.
Şimdi modlarını anlatalım. 1. Kullanım Modu: EXG D3, D5 D3 data registerinin içerdiği sayıyı, D5 data registerinin içeriğindeki sayı ile değiştir.
Örneğin; D3 data registerinde $0FFF0000 olduğunu ve D5 data registerinde de $000F0000 olduğunu varsayalım. EXG D3, D5 komutu işleme girdiğinde registerlerin içindeki sayılar yer değiştirecek ve $000F0000 sayısı D3'e ve $0FFF0000 sayısı ise D5'e gidecektir. 2. Kullanım Modu: EXG A0,A1 A0 adres registerindeki sayıyı, A1 adres registerinin içindeki sayı ile değiştir. 3. Kullanım Modu: EXG D3, A3 D3 data registerindeki sayıyı, A3 adres registerindeki sayı ile değiştir. 4. Kullanım Modu: EXG A0, D1 A0 adres registerindeki sayıyı, D1 data registerindeki sayı ile değiştir.
Gelecek ay makine dilindeki atlama ve dallanma komutlarını inceleyeceğiz. Şimdilik hoşça kalın.
Klavyeyle gezinmek için ← ve → tuşları.
Sayfa 36
WORD ve BYTE modlarında kullanarak, data registerleri arasında birer veya ikişer gruplar halinde de toplama işlemi yapabiliriz.
5. Kullanım Modu : ADD.L A0, A1 A0 adres registerindeki değerin, A1 registerindeki değere eklenmesini sağlarız. Bu mod hakkında bilmemiz gereken bir şey daha var: ADD komutu ile bir adres registerindeki değeri, başka bir adres registerine toplatırken sadece WORD ve LONGWORD olarak çalışmamız gerekir.
6. Kullanım Modu : ADD.L $50000, A0
$50000 hafıza adresindeki sayı, A0 adres registerindeki değere eklenir.
7. Kullanım Modu : ADD.L $50000, D0
$50000 hafıza adresindeki sayı, D0 data registerinin içindeki sayıya eklenir. 8. Kullanım Modu : ADD.L (A0), D1 örneğimizde A0 adres registerinde bulunan adresin gösterdiği sayıyı D1 data registerinde bulunan sayıya eklemesini ifade etmiş oluyoruz.
Bu arada registerler hakkındaki bilginize yeni bir şey daha eklemek istiyorum. Yukarıdaki örnekte olduğu gibi parantez içinde sadece Adres Registerleri yazılabilir. Data registerleri ise sadece taşıma ve saklama işlemleri için kullanıldıkları için parantez içinde kullanılamazlar. Daha önce de öğrendiğimiz gibi; Parantez içindeki adres registeri ifadesi, aynı adlı adres registerinin gösterdiği adresin hafıza adresine karşılık gelen sayının anlamında kullanılmasıdır. Biraz karışık olduysa aşağıdaki örnek ile daha iyi anlayacaksınız.
1- LEA $50000, A0 MOVE.L (A0), $60000 2- MOVE.L $50000, $60000 1. örneğimizin ikinci satırı ile 2. örnek arasında işleyiş bakımından hiçbir fark yoktur. Fakat 1. örnekteki kullanım ikincisinden çok daha esnek oluyor. Registerdeki sayıyı rahatlıkla değiştirerek aynı işlemi yeni adres için tekrarlayabiliriz. Tabii bundan başka iki kullanım arasında mükemmel bir hız farkı olduğunu söyleyebilirim. Çünkü işlemci, komutun ilk parametresini değer olarak komutun bulunduğu adresten almak yerine, doğrudan içindeki adres registerlerinden okuması çok daha hızlı ve seri oluyor. 9. Kullanım Modu : ADD.L D0, (A0) ADD komutu burada D0 data registerindeki sayıyı, A0 adres registerinin gösterdiği adresteki sayıya ekleyecektir.
ADDQ KOMUTU ADDQ komutu, genel olarak ADD komutu formatında çalışır, özelliği bazı işlemleri ADD komutundan çok daha hızlı yapabilmesidir. Fakat bu hızlı çalışması 1'den 8'e kadar olan sayıların toplanması için geçerlidir. Ve ADDQ ile bu işlemleri ADD komutundan 2 kat daha hızlı olarak yapabilirsiniz. Tabii komut BYTE, WORD, LONGWORD kullanımları destekliyor.
Komut ile ADDQ.L #1, D0'den ADDQ.L #8, D0'e kadar olan toplamaları rahatlıkla yapabileceksiniz. Fakat 9 ve 9'dan büyük sayıları kullanmak isterseniz, mecburen ADD komutunu kullanmak zorundasınız. ADDQ komutunun kullanım modları aynen ADD komutundaki gibidir.
Şimdi diyeceksiniz ki; zaten bilgisayarımız 7.16 MHz ile çalışıyor. Yani bir saniyede yaklaşık 1 Milyon toplama işlemi yapıyor. Ne gerek var ki 1'den 8'e kadar olan toplamalarda ADDQ kullanmaya?
Aslında hiç de düşünüldüğü gibi olmuyor. Zamanla makine dilinde yapılan işlemlerin 1 ve 8'leri toplamaktan başka bir şey olmadığını göreceksiniz. Ve bilgisayarınızın grafik işlemlerini düzenlerken bol bol taşıma yapıp, bir hafıza bölgesindeki sayıları başkalarına ekleyip, bol bol toplama çıkarma işlemi yapıldığına şahit olacaksınız.
Tabii hal böyle olunca, ADDQ gibi ufak sayılarla hızlı işlem yapan komutlar, profesyonel programcıların vazgeçilmez araçları oluyor.
SUB KOMUTU
Çıkarma işlemleri için bu komutu kullanacağız. İşleyişi ADD komutu ile benzerlik gösterir. Tek fark verilecek sayının değerinin ikinci sayının değerinden çıkarılmasıdır. Komutu Byte, Word, Longword olarak üç modda da kullanabiliriz. Sub komutu da Add komutu gibi hexadecimal olarak $00000000'dan tutun $FFFFFFFF'e kadar olan sayıları rahatlıkla birbirlerinden çıkarabilir.
1. Kullanım Modu: SUB.L #10, D0 veya SUBI.L #10, D0
Yukarıdaki yanyana yazılı iki örnek de aynı anlama gelmektedir. D0 data registerindeki değerden 10 çıkarıyoruz. Çıkarma işlemi sonucunda ortaya çıkan sonuç D0 registerine yazılmaktadır.
2. Kullanım Modu: SUB.L #255, A0 veya ADDA.L #255, A0 örnekte A0 adres registerindeki sayıdan 255 çıkarıp sonucu A0'a tekrar yazıyoruz.
3. Kullanım Modu: SUB.B #$10, $50000
$50000'deki sayıdan 10 çıkarıyoruz. Yukarıdaki örneğimizi SUB.L #$10, $50000 diye değiştirirsek, çıkarma işlemi $50000'deki 4 BYTE'ı birden etki eder. Tabii örnek böyle olunca sayımız LONG
WORD olarak işleme giriyor. Ve $50000'den $50003'e kadar olan dört hafıza bölgesinde saklanıyor. Bu arada bilmeniz gereken başka bir nokta da şudur:
Diyelim ki, $50000 hafıza adresinde LONGWORD olarak $00000000 olsun. Ve bir "SUB.L #1, $50000" komutu ile $50000'deki LONGWORD sayıyı bir eksiltmek istedik. Fakat zaten adresteki sayı $00000000. Çıkarma işlemi olursa sayı eksi işaretli bir sayı olacak. Fakat hafıza bölgesindeki bu sayının eksi gösterilmesi nasıl olacak? Bu gibi durumlarda bilgisayar şöyle bir mantık yürütüyor: LONGWORD olarak en büyük sayı $FFFFFFFF olduğuna göre, $00000000'dan sayı çıkarılırsa eksi yerine $FFFFFFFF'den geriye doğru sayı çıkarılıyor. Eksi işareti ise, NEGATIVE bayrağından okunabiliyor.
Makine dilinde örnekteki gibi $00000000'dan 1 çıkarsa, sonuç $FFFFFFFF olur. Aynı mantıkla $00000000'dan 5 çıkarırsak sonuç $FFFFFFFB olur.
4. Kullanım Modu: SUB.L D0,D1 Bu komut ile D0 data registerindeki LONGWORD değeri D1 registerindeki değerden çıkarmasını ifade ediyoruz. Komutu aynı şekilde LONGWORD yerine WORD ve BYTE modlarında kullanarak data registerleri arasında birer veya ikişer gruplar halinde de çıkarma işlemi yapabiliriz. 5. Kullanım Modu: SUB.L A0,A1 A0 adres registerindeki değeri, A1 registerindeki değerden çıkarmasını sağlarız. Bu mod hakkında bilmemiz gereken bir şey daha, SUB komutu ile bir adres registerindeki değeri, başka bir adres registerinden çıkarırken sadece WORD ve LONGWORD olarak çalışmamız gerektiğidir. 6. Kullanım Modu: SUB.L $50000,A0 $50000 hafıza adresindeki sayı, A0 adres registerindeki değerden çıkarılır. 7. Kullanım Modu: SUB.L $50000, D0 $50000 hafıza adresindeki sayı, D0 data registerinin içindeki sayıdan çıkarılır. 8. Kullanım Modu: SUB.L (A0), D1 örneğimizde A0 adres registerinde bulunan adresin gösterdiği sayıyı D1 data registerinde bulunan sayıdan çıkarılmasını ifade etmiş oluyoruz. 9. Kullanım Modu: SUB.L D0, (A0) SUB komutu burada D0 data registerindeki sayıyı, A0 adres registerinin gösterdiği adresteki sayıdan çıkaracaktır.
SUB komutunun parametrelerini de gördükten sonra şimdi SUBQ komutunu anlatalım.
SUBQ KOMUTU SUBQ komutu ADDQ gibi işlem yapar. SUB komutundan farkı ise, 1'den 8'e kadar olan sayılarla işlem yapması ve SUB komutundan iki kat hızlı iş görmesidir.