Z80 Assembly I

Z80 Assembly I
Yazi serisinin bir sonraki makalesi Z80 Assembly girisi hakkinda. Biliyorum, 1970'lerde yapilmis, 8-bit bir islemci pek cok kisinin ilgisini cekmez ama yazilar genel hatlariyla gunumuz mimarilerine oldukca benzediklerinden ve kismen de olsa ilgi cekecegini dusundugumden dolayi paylasiyorum. Z80 hakkinda detayli bilgi isteyenler Zilog_Z80 Wiki inceleyebilirler.

Z80 Mikroislemci Mimarisi
Bir onceki yazimiz genel mikroislemci mimari konseptlerini kapsiyordu. Bu yazimizda, programlama bakis acisindan Z80 mimarisini inceleyecegiz, bu esnada yararlanacagimiz kaynak ise Z80 kullanici kitapcigi: 


Asagidaki yaziyi gelecekte referans kaynagi olarak kullanmakta ozgursunuz.

Z80 Block Diagrami


Genel mikroislemcilerdeki block diagramini hatirliyor musunuz? Hatirladiysaniz, yukaridaki resimde Z80 mikroislemcisine ait block diagramdir. Gordugunuz uzere iki diagram arasinda oldukca benzer yapilar mevcut. Buradaki diagramda da Control Unit, ALU, register ve bus yapilarimiz var.

Z80 Address Bus
Z80 mikroislemcisindeki adres yolunun 16-bit oldugunu goruyoruz, bu da demek oluyor ki islemcinin adres yolu direk olarak 65.536 byte (64kb) boyutunda adreslenebilir. Adresler 0 degerinden baslamasindan ve adreslerin toplam boyutunun 65.536 olmasindan dolayi, Z80 icin baslangic adresi 0x0000 (0000), bitis adresi 0xFFFF (65.536) degerleridir. Bu noktada bank switching isimli bir teknik durum soz konusu. Bank switching, mikroislemcinin izin verilen adres uzayinin disinda baska adres degerlerine de erisebilmesine izin verilmesi islemidir fakat suan icin erisilebilir hafizayi 64kb olarak dusunebiliriz.

Onemli olan bir nokta, Z80 yeniden baslatildigi zaman, baslangic talimatlarini 0x0000 adresinden almasidir. Bu sebeple, ROM adi verilen kalici hafizayi, adres degeri kucuk olan kisimlarda bulacagiz. Kalici olmayan RAM adresleri ise daha buyuk adres degerlerinde olacaktir.

Z80 Register


Z80 icin programlamaya baslanildigi zaman, en cok zaman harcanan kisim kaydediciler ile calisma kismidir. Z80 bize, her biri 6 adet genel amacli kaydedici (accumulator ve flag) iceren temel ve alternatif olmak uzere 2 cesit kaydedici kumesi saglar. Alternatif kaydediciler extra hafiza uzaylari icin kullanilir, biz simdilik temel kaydedici kumesine odaklanacagiz.

Temel ve alternatif kaydedici kumelerine ek olarak bir de ozel amacli kaydediciler vardir. Bu kaydedicilerin icerisinde sayisi belli olan, index kaydedicileri, stack kaydedicileri ve program sayaclari bulunur.

General Purpose Registers
Z80, 6 tane genel amacli kaydedici saglar: B, C, D, E, H ve L. Bu kaydedicilerden her biri 8-bit genisligindedir, bu da demek oluyor ki bu kaydediciler 0x00 (0) ile 0xFF (2^8 = 255) arasindaki degerleri saklayabilirler.

Genel amacli kaydediciler, 16-bit degerleri gosterebilmek icin birlikte kullanilabilirler. Bu, 16-bitlik matematik islemlerine veya 16-bit adres yolu degerlerine izin verirler manasina gelmektedir.

16-bit genel amacli kaydediciler BC, DE ve HL kaydedicileridir. Ornegin; eger kaydedici B icerisinde 0x12, C icerisinde 0x34 degerleri varsa, BC kaydedicisi 0x1234 degeri icerir.

Hafiza (accumulator) ve bayrak (flag) kaydedicileri gecerli bir degeri gostermek icin AF olarak genisletilirler ama bu islemin faydasini genel itibariyle, Z80 programlandigi zaman degil Z80 programlarini debug ederken goruruz.

Index Registers
Z80, IX ve IY adinda 2 tane 16-bit indeks kaydedicisi saglar. Bu kaydediciler, bir adresi gostermek kullanilirlar. Ayrica diger kaydedicilerdeki degerler icin, bu adresteki deger offset olarak kullanilir.

Paketlenmis verilere sahip oldugunuz, verinin genisligini bildiginiz ve bu verinin belli bir kismi uzerinde islem yapmak istediginiz zaman bu kaydediciler tercih edilir. Bu kavram, daha yuksek programlama dillerinde, ayni tip birden fazla veri saklama isini organize eden, bir veriden 
digerine gecebilen ve bir offset ile belirtilen 'array' olarak bilinir.

Ornegin; bir oyunda en yuksek skorlarin kaydedildigi bir tabloya sahibiz. Bu tablo 0x1000 adresinde bulunuyor ve tum skorlar 5 byte boyutunda bilgiler iceriyor. Eger IX kaydedicisi 0x1000 degerine esit olursa, birinci en yuksek skor IX + 0x00 adresinde, ikinci en yuksek skor IX + 0x05 adresinde saklanir ve bu sekilde devam eder. Burada, indeks degerini genel amacli bir kaydedicide sakliyoruz ve istedigimiz zaman skorlari bu kaydediciyi 0x05 kadar artirarak dolasabiliyoruz.

Accumulator Register
Hafiza kaydedicisi (A) otomatik olarak, tamamlanmis talimatlarin sonuclarini icerir. Bu kaydedici, cogunlukla diger genel amacli kaydediciler gibi kullanilabilir fakat matematiksel veya mantiksal islemler, A kaydedicisi icerisinde sakladiginiz degerleri degistirebilir.

Flag Register
Bayrak kaydedicileri, 8 farkli boolean sonucunu saklayan bit dizimlerini icerirler. Bu bitler calistirilan talimatlarin sonuclarina bagli olarak degisirler. Z80 ile calismaya baslar baslamaz tum bayrak kaydedicilerini tam olarak kullanacagiz.

Program Counter Register
Program sayac kaydedicileri veya kisaca PC kaydedicileri hafizadan alinan talimatlarin adreslerini tutan 16-bit kaydedicilerdir. Bir talimat islendikten sonra bu kaydedici bir sonraki talimati alabilmek icin 1 artirilir. Z80 mikroislemcisi yeniden baslatildiginda PC kaydedicisi 0x000 adresini gosterir, boylece ilk talimati alir ve ondan sonra artarak devam eder.

Stack Pointer Register
Stack pointer kaydedicisi, stack yapisinin en ustundeki hafiza adresini gosterir. Stack, hafizada gecici bir adres uzayi olarak kullanilir.

Konsept olarak stack, en son koydugumuz elemani ilk olarak alabildigimiz ve tum elemanlarina birer birer erisebildigimiz, herhangi bir tipteki ogeler yiginidir. Tam tersi olarak ilk koyulan eleman da bu yigindan en son cikarilir. Bu ozellik Last In First Out (LIFO) olarak bilinir. Ilerleyen zamanlarda push ve pop gibi talimatlari islerken stack uzerinde daha cok duracagiz.

Z80 Interrupts and Interrupt Handlers
Interrupt, harici bir cihazin bir mikroislemci ile konusmasina izin verir. Bu cihazlar, buton veya joystick, bir klavyede basilabilen bir tus veya donanimin diger parcalarinin herhangi birisi olabilir. Interrupt, Z80 bir is yaparken onu durdurur, kendi icerdigi kodu calistirir ve yapmak istedigi isleme devam eder.

Interrupt'lar ikiye ayrilirlar: maskable (maskelenebilir) ve non-maskable (maskelenemez). Bu iki tip arasindaki fark, maskelenebilen interrupt'lar yazilim tarafindan engellenirken maskelenemeyen interrupt'lar bir yazilim tarafindan engellenememesidir. 

Maskelenebilen interrupt'lar icin interrupt cevaplarini yakayabilen bir cok baska interrupt cevap modu olmasina ragmen maskelenemeyen interrupt'lar offset 0x66 degerinde yakalanirlar.

Mode 0 Interrupts
Mode 0 interrupt'lari, bir cihazin islemciye calistirilmak uzere bir talimat saglamasina izin verirler ve yeniden baslama talimati araciligiyla bu cihazin kontrolunu islemciye devrederler.

Mode 1 Interrupts
Mode 1 interrupt'lari, maskelenemeyen interrupt'lar gibi calistirlar, tek farklari offset 0x66 yerine offset 0x38 degerinde calistirilan cihazlarin yakalanmasini saglarlar.

Mode 2 Interrupts
Mode 2 interrupt'lari, interrupt yakalayici kodlarin calisma duzenini iceren 16-bitlik hafiza bilgilerini saklayan bir adres tablosunun guncellemesine izin verirler. Bu adres tablosu, hafizadaki sabit degerlere sahip degildir, adresler, interrupt cihazlari tarafindan dondurulen 8-bitlik bir deger ile genisletilmis veya 8-bit genisligine sahip ozel amacli kaydedicilerin yuklenmesi ile belirlenir.

ENDIANNESS
Z80, Cyber_kes little endian bir islemci olarak bilinir. Bunun anlami, bir verinin hafizada saklanan birden cok byte degeri oldugunda bu byte degerlerinin en onemsiz byte'i ilk byte, en onemli byte'i ise son byte olacak sekilde ayarlanmasidir. Ornegin; 0x1234 16-bit degerinin little indian gosterimi 0x3412, 0x12345678 32-bit degerinin little endian gosterimi 0x78563412 seklindedir.

Z80 icin program yazilirken, verinin ters bir sekilde saklandigini bilmek pek yararli degildir ama bu bilgi debug ve reverse engineering uygulanmasi sureclerinde paha bicilemez bir bilgidir.

Bir sonraki yazida bir miktar Z80 assembly yazmaya baslayacagiz.

Popular posts from this blog

Polya’nın Problem Çözme Teknikleri

Mikroislemci Temelleri