Amiga Dünyası sayı 19, sayfa 29

Bu sayfadaki yazılar

Sayfanın metni

Sayfa 29

gerekmekte.

Direkt adreslemede bu değişmekte. Şayet bir adresteki değeri '.B' takısını kullanarak etkilersek, o adresteki byte değişir. '.W' takısı o adresteki ve adresten sonraki byte'ı değiştirir. '.L' takısı da o adreste yer alan longword'u etkileyeceğinden, adresten sonraki 4 byte birden komutumuza göre değişir. Aşağıda bu konuyla ilgili basit örnekler yer almakta: CLR.L D0 ==> D0 içeriğini komple temizler. MOVE.W D5,D3 ==> D5'in alt word'unu (bit 0-bit 15)

D3'e kopyalar. MOVE.W $50000,D2 ==> $50000'de yer alan word'u (ilk iki byte) D2'ye kopyalar. MOVE.L $42000,A0 ==> $42000'de yer alan longword'u

A0'a kopyalar. 8. Örnek 10.1'de 'MOVE.L D0,INTBASE' komutu var, sonra 'BEQ EXIT3' komutu var ama CMP komutu yok, o zaman karşılaştırma nasıl olacak?

C. Birçok komut işlem yaparken aynı zamanda flag'leri de etkiler. Bu yüzden bu tür bir komut kullandığınızda ekstradan bir CMP komutu daha kullanmanız gerekmez. Flag'leri etkileyen komutlardan bazıları: MOVE, AND, ADD, ASL, BSET, BCLR, BTST, CMP, DIVU, EOR, LSR, MULU, NEG, NOT, OR, ROL, RTE, RTR, SUB, SWAP, TAS, TST.

9. Son örneklerde 'BEQ.L' görülüyor, longword olması ne işe yarar? Bir de mesela 'BEQ.S' deniyor. '.S' neyi ifade ediyor?

C. Bu takılar arasında ufak bir fark var. 512 byte'lık sınırlar içinde yakın bir label'a dallanmak istediğinizde, bunu ister BEQ.S, isterseniz de BEQ.L komutuyla yapabilirsiniz. BEQ.S komutunu kullandığınızda assemble edilmiş programda bir word tasarruf edersiniz. BEQ.S komutu ve ardından gelen label hafızada bir word yer kaplar. Oysa BEQ.L kullandığınızda, bu 2 word olmakta. Gördüğünüz gibi pek fazla bir şey fark etmiyor. Dilerseniz Seka'da assemble ederken 'O' opsiyonunu kullanarak Seka'nın tüm bu takıları yerleştirmesini sağlayabilirsiniz. Bu takılar tüm dallanma komutları için geçerli.

10. 'MOVE.L 4A6' gibi durumlarda adresin atanacağı register fark eder mi?

C. Hayır. A6 register'ının kullanılış nedeni, herkesin bu register'ı kullanmasıdır. Dilerseniz A0'ı da kullanabilirsiniz. Ama bu durumda JSR -$nnn(A6) komutlarını da değiştirmeniz gerekmekte. Şimdiye kadar hiçbir programda farklı bir adres register'ının kullanıldığını görmedim. Ama bu kullanılmaz anlamına gelmez.

11. 'JMP -$228(A6)' neden (A6) ile toplama gereği duyuluyor, direkt adres yazılsa olmaz mı? Yoksa format mı öyle?

C. Bunun sebebi library adreslerinin hafızada düzenlenişi ile ilgilidir. Bütün Amiga'larda yazılan programların hatasız çalışabilmesi için sistemi hazırlayan programcılar biraz dolaylı bir yöntem kullanmışlar. Fakat bu dolaylı yöntemin en büyük avantajı, yeni bir KickStart versiyonu çıktığında sorun olmadan her programın çalışabilmesidir. Bu nasıl gerçekleşmekte? Bunu anlamak için library'lerin hafızadaki durumlarına kısaca bir göz atalım.

Bütün çok kullanılan library'ler hafızada sabit olarak bulunmaktadırlar. Library fonksiyonlarının yerleştiği adresler, $fc0000 ve yukarısıdır. Tabii bu, yeni Amiga'lar olan A-3000 ve A-3500'lerde değişmekte. Fakat şu an herkesin normal Amiga'lardan (KickStart v1.2 ya da v1.3) kullandığını farz edelim. Bir library'i açtığımızda aslında yapılan işlem bir tablonun RAM'e kopyalanmasıdır. Bu tablo aslında bir dallanma tablosudur. Burada o library'nin bütün fonksiyonlarının gerçek adreslerine dallanan JMP komutları görülmekte. KickStart versiyonun değiştiğini kabul edelim. ROM'daki bazı rutinler değişmiş olacak. Bazıları uzamış, bazıları da kısalmış olacak. Bu durumda bütün library fonksiyonlarının adresleri değişecek. Eski bir Amiga'da direkt adresler kullanılarak yazılan bir program, tümüyle hatalı çalışacaktır. Fakat sistemi yaratanlar, dallanma tablosu kullanarak sadece tablodaki adresleri değiştirmekle tüm uyumsuzluğu ortadan kaldırmışlar. Library'lerden herhangi birini açtığımızda, bu library'nin başlangıç adresi bize D0 register'ı sayesinde aktarılıyor. Base adresten sonraki değerler o library'e ait bazı önemli datalardır. Biz bu dataların tümüne BASE STRUCTURE adını veriyoruz (ExecBase Structure gibi). Base adresinden ÖNCE ise, tüm dallanma tablomuz yer almakta. Bu dallanma tablosuna da erişmek istiyorsak, -nnn(a6) adresleme şeklini kullanmalıyız. Tabii aynı şekilde şöyle de yazabilirdik:

move.I 4,a6 sub.l #$-228,(a6) jmp (a6)

Fakat bu, hem programımızı boşu boşuna uzatacak, hem de her seferinde a6 register'ının içeriğini bozacaktır.

12. BSR komutunun görevi nedir? C. BSR ve JSR komutları dönüşlü dallanmayı sağlarlar. Bunun anlamı şudur: İlk önce komutun yer aldığı satırın altındaki satırın adresini stack'e atar. Sonra komuttan sonra verilen label'a ya da adres'e dallanır. Oradaki tüm işlemleri gerçekleştirdikten sonra, RTS (ReTurn from Subroutine) komutuna rastladığında stack'teki adresi alır ve o adrese zıplar. Altrutinlerden RTS yerine yine bir dallanma komutu kullanırsak, dönüş adreslerinin her seferinde stack'e atıldığını unutmayın. Altrutinden RTS yerine JMP ya da BRA gibi bir komutla ana rutine dönerseniz, stack'teki adres silinmeyecektir. Ana programınızın sonunda da RTS komutuna rastladığında stack'teki adrese dallanmak isteyecektir. Bu da hata yaratacak, belki de bilgisayarınızı crash ettirecektir.

13. 'MOVE.L D0,WINBASE'deki window durum bilgileri nedir?

C. Library açtığımızda D0 register'ında bu library'nin base adresi yer alır. Bu base adresinden sonra gelen tüm datalar o library hakkında önemli bilgiler taşıyan LIBBASE STRUCTURE'una aittir. Daha ilerde bu structure'ları detaylı olarak inceleyeceğiz. Biz şimdilik library base adresini, o library'e ait fonksiyonlara erişmek için kullanıyoruz. Library base adresinden önce gelen dallanma tablosu sayesinde library fonksiyonlarına erişebiliriz.

14. 'DC' yani data satırı ile kullanılan '.L', '.W' ve '.B' takıları neyi değiştirir? Önemli olan onu oradan nasıl aldığımız değil mi?

C. Data satırlarında 'DC' komutundan sonra kullanılan takı ile sayıların takıya göre aynı bit uzunluklarında olmaları sağlanmakta. Eğer bir 'DC.W' satırı kullanırsak ve MOVE.L ile buradan bir sayı almaya kalkarsak, alınan sayı iki word olacaktır. Oysa data satırlarında DC.L kullandığımızda sayımızı doğru olarak okuyabiliriz. Aynı şekilde data satırlarında DC.L kullanıp MOVE.B ile ilk sayıyı okuduğumuzda, genelde 0 elde ederiz. DC.L ile her sayıya 4 byte rezerve edilmekte ve sayımız 256'dan küçükse (byte sınırını aşmıyorsa) longword'umuzdaki ilk üç byte değişmemektedir. Eğer sayı word sınırını aşmıyorsa, bu sefer longword'daki ilk iki byte 0 değerini alacaktır.

Umarım Tolga arkadaşımızın tüm sorularını anlayabileceği bir şekilde cevapladım. Bu sorular sayesinde bazı bilinmeyenlere de ışık tutmaya çalıştım. Fakat hala kafanızı kurcalayan sorunlarınız olduğunda bana yazmaktan çekinmeyin. Ehh, artık bu ayki bölüme ne yazık yer kalmadı. Bu yüzden bu ay sadece programımızı yayınlayacağım. Programın açıklamasını da artık gelecek ay göreceğiz. Ayrıca programı açıkladıktan sonra gelecek ay tüm assembler komutlarının listesini ve kullanılışlarını vereceğim.

************************************************************** ** AMIGA DÜNYASI AMIGA ASSEMBLER KURSU ** ** INTUITION LIBRARY - WINDOW EXAMPLE ** ** ORNEK 19.1 ** ************************************************* START: movem.l d0-d7/a0-a6,-(sp) bsr.s IMTLIBS bsr.L IMTSCREEN

Klavyeyle gezinmek için ← ve → tuşları.