Merhaba, Ziyaretçi. Lütfen giriş yapın veya üye olun.

Kullanıcı adınızı, parolanızı ve aktif kalma süresini giriniz

  Gelişmiş Arama
insanın içinde varsa, commodore.gen.tr açığa çıkarır bunu.. bir nevi retro olaylarının dolunayıyız.(Arda)
Sayfa: [1]   Aşağı git
Yazdır
Gönderen Konu: Z-80 ASSEMBLER ÖĞRENİYORUZ.  (Okunma Sayısı 15790 defa)
0 Üye ve 1 Ziyaretçi konuyu incelemekte.
hades
Üye
****
Mesaj Sayısı: 332



Üyelik Bilgileri
« : Aralık 30, 2008, 21:07:15 ÖS »

Hazır Z80 code kasmaya başlamışken bildiklerimizi burada paylaşıp bilmediklerimizi öğrenmek için bu başlığı açtım.
Bu bölümü sadece bilgi paylaşma ve konuyla ilgili olmak şartıyla soru/cevap şeklinde kullanalım.

İyi bir öğretmen değilim, kendi çapımda birşeyler bilirim, ama iş anlatmaya, açıklamaya gelince herşey birbirine karışabilir. Şimdiden belirteyim.

DERS 1

Z80 8 bitlik bir mikroişlemcidir. 8 data hattına ve 16 adres hattına sahiptir. 16 adres hattıyla 65536 bellek hücresi adreslenebilir ve bunlar adresler 0 ... 65535 arasındadır. Bu adres aralığı ZX-spectrumda, 0 ... 16383 arasında ROM, 16384 ... 65535 arasında RAM olarak belirlenmiştir. (Spectrum'un bellek düzeni ayrı bir yazı konusudur.)

Bir "byte" 8 "bit" ten oluşur ve bir "bit" sadece "0" veya "1" değerini alabilir. Buna göre bir byte 00000000 ..... 11111111 arasında 256 değer alabilir. Bu değerler 0 ... 255 arasında yazılabilir.
Her bitin bir sayı değeri vardır. Bitler sağdan sola doğru dizilmiştir ve 0. bit, 1. bit ..... 7. bit olarak tanımlanır.

Bitler : 7 6 5 4 3 2 1 0

0. bit : 1
1. bit : 2
2. bit : 4
3. bit : 8
4. bit : 16
5. bit : 32
6. bit : 64
7. bit : 128

değerine sahiptir. Bu sayıları toplarsak 255 değerini elde ederiz. Z80'de herhangi bir biti "0" veya "1" yapmamızı sağlayan komutlar bulunmaktadır.

Bu kısa bilgilerden sonra yavaş yavaş komutlara giriş yapabiliriz.

Komutları genel olarak birkaç gruba ayırabiliriz. (unuttuklarım olabilir.)

1-Yükleme komutları/yığın komutları
2-Sıçrama/geri dönüş komutları
3-Aritmetiksel/mantıksal komutlar
4-Arttırma/azaltma komutları
5-Kaydırma/döndürme komutları
6-Karşılaştırma komutları
7-Bit düzeyinde işlem yapan komutlar
8-Blok işlem yapan komutlar/giriş-çıkış komutları

Komutları görmeye başlamadan önce register kavramını inceleyelim.
Her mikroişlemcide bulunan ve adına register denilen işlem birimleri vardır.
Bu registerler ile yükleme, aritmetik işlemleri vs. yapılır. Z80'de A, B, C, D, E, H, L, Flag, SP, IX, IY registerleri vardır. SP, IX ve IY 16 bitlik register, diğerleri 8 bitlik registerdir. Ayrıca B ve C registerleri bir araya gelerek 16 bitlik BC registeri olarak kullanılabilir. Aynı durum D ve E, H ve L registerleri içindir. Böylece elimizde kullanma durumuna göre 3 adet daha 16 bitlik register hazır olur.
Flag registeri, o an işlenen bir komuta, yapılan işe göre çeşitli durumlar alabilen ve her biti farklı amaçlar için kullanılan bir registerdir. Mesela bir toplama işleminde "elde" var mı, sonuç "0" mı gibi durumları belirten bir registerdir. Bazı işlemlerde bu "durum"ları kontrol etmemiz/değiştirmemiz ve program içinde şartlı işlemler yapmamız gerekebilir.
« Son Düzenleme: Ocak 16, 2009, 19:58:46 ÖS Gönderen: hades » Logged
hades
Üye
****
Mesaj Sayısı: 332



Üyelik Bilgileri
« Yanıtla #1 : Aralık 30, 2008, 21:26:07 ÖS »

DERS 2 - YÜKLEME KOMUTLARI :

Yükleme komutları bir registere, bir register çiftine veya bir adrese sabit bir sayı, başka bir registerin içeriği veya herhangi bir adresin içeriğini yüklemek için kullanılır.

Derslerimizde daha anlaşılır olması bakımından aşağıdaki kısaltmaları kullanacağız.

Komutun biçimi LD hedef,kaynak şeklindedir.

d : mesafe,
r : register,
rp : register çifti,
nn : bir baytlık sayı,
nnnnn : iki baytlık sayı,
(nnnn) : adres,
(rp) : Bir register çiftinde bulunan sayının belirttiği adresin içeriği anlamına gelmektedir.

ÖRNEK : LD BC,16384 olsun, LD A,(BC) komutuyla, BC register çiftinde bulunan 16384 numaralı adresin içeriği Aküye yüklenir.

Z80'de oldukça çok adresleme modları vardır ve bunları bilmemiz gerekiyor.


1- LD r,nn --> Bir registere bir baytlık sayı yüklenir.

Örnek : LD A,0 ---> A registerine (Aküye) sabit 0 sayısı yüklenir.
Örnek : LD L,255 -> L registerine 255 sayısı yüklenir.

Bu adresleme modunda A,B,C,D,E,H,L registerlerine bir baytlık sabit sayı yüklenir.
Bu adresleme moduna LD (HL),nn ;LD (IX+d),nn ve LD(IY+d),nn komutlarıda dahildir. Son üç komut ile ilgili registerlerin gösterdiği adrese nn sabit sayısı yüklenir.


2- LD rp,nnnn ---> Bir register çiftine 2 baytlık bir sayı yüklenir.

Örnek : LD BC,32000 ---> BC register çiftine 32000 sayısı yüklenir.
Örnek : LD HL,0 -------> HL register çiftine 0 sayısı yüklenir.

Bu adresleme modunda BC,DE,HL,IX,IY ve SP registerlerine iki baytlık sabit bir sayı yüklenir.


3- LD r,r ---> Bir registere başka bir registerin içeriği yüklenir.

Örnek : LD D,A ----> D registerine A registerinin içeriği yüklenir. D ile A'da aynı değer bulunur. A'nın içeriği kaybolmaz.

Bu adresleme modunda A,B,C,D,E,H,L registerlerinin herhangi birinden herhangi birine yükleme yapılır. Kaynak ve hedef registerler aynı olabilir. Yani LD C,C gibi bir komut olabilir.
Ayrıca I (İnterrupt) ve R (Refresh) registerleri sadece A registeriyle birlikte kullanılır. Yani sadece LD I,A ; LD R,A ; LD A,R ve LD A,I komutları olabilir.


4- LD rp,rp ----> Bu adresleme modunda sadece SP registerine HL, IX veya IY registerlerinden yükleme yapılabilir.


5- LD (rp),r ----> Bu modda ise A,B,C,D,E,H ve L registerlerinden herhangi birinin içeriği (HL), (IX+d), (IY+d) 'ye yüklenir.
Bu registerlerden sadece A registeri (BC), (DE) ve (nn) ile birlikte kullanılabilir.

HATIRLATMA : Parantez içindeki ifadeler, ilgili registerlerin kendisine değil, gösterdikleri adrese yükleme yapılacağını belirtir.
ÖRNEK : LD BC,60000 ile BC registerine 60000 sayısısı yükleyelim. LD A,210 komutu ile aküye 210 sayısını yükleyelim. LD (BC),A komutu ile Aküdeki 210 sayısını 60000 adresine yüklemiş oluruz. Eğer hedef adres sabit ise, register çifti kullanılmadan LD (nnnn),A komutuyla ilgili adrese yükleme yapılır. Örneğimizden devam edersek LD A,210 ; LD (60000),A şeklinde kullanabiliriz.

6- LD r,(rp) ----> Bu modda bir register çiftinin gösterdiği adresin içeriği A,B,C,D,E,H,L registerlerinden birine yüklenir. (rp) ise (BC),(DE),(HL),(IX+d),(IY+d),(nnnn) olabilir. (BC),(DE) ve (nnnn) sadece A ile birlikte kullanılabilir.

ÖRNEK : LD HL,22528 ; LD D,(HL) Bu örnekte HL registerinde belirttiğimiz adresin içeriği D registerine yüklenir. Eğer kaynak adres sabit ise LD A,(nnnn) komutu kullanılabilir.

Son iki adresleme modu biraz karışık olup dikkatli kullanmak gerekir.

7- LD rp,(nnnn)----> Bu adresleme modunda kaynak adresteki sayının kendisi değil, sayının belirttiği adresin ve bir fazlasının içeriği yüklenir.
ÖRNEK : 60000 adresinde 100, 60001 adresinde ise 20 olsun. LD HL,(60000) komutunu verdiğimizde HL'ye 60000 değil  256*20+100 sayısı yüklenir. Formül 256*(nnnn+1)+(nnnn)'dır.

Bu modda BC,DE,HL,IX,IY ve SP registerleri kullanılır.


8- LD (nnnn),rp ----> Yukarıdaki adresleme modunun tersidir ve herhangi bir register çiftindeki sayıları (nnnn) ve (nnnn+1) ile belirtilen adreslere kopyalar.
ÖRNEK : LD HL,22528 ; LD (30000),HL  komutlarıyla HL register çiftinde bulunan 22528 sayısın LOW-BYTE'ı 30000 adresine, HIGH-BYTE'ı 30001 adresine yüklenir.

Bu son modda da BC,DE,HL,IX,IY ve SP registerleri kullanılır.

EK BİLGİ : BC,DE,HL register çiftlerinde kullanılan ilk harfler HIGH byte, ikinci harfler LOW byte değerini taşır.


Yükleme komutlarında kullanılan adresleme modları bu kadar.

« Son Düzenleme: Ocak 01, 2009, 20:27:18 ÖS Gönderen: hades » Logged
ilkergorkem
Üye
***
Mesaj Sayısı: 179



Üyelik Bilgileri
« Yanıtla #2 : Ocak 01, 2009, 16:27:36 ÖS »

Alıntı
Örnek : LD A,0 ---> A registerine (Aküye) sabit 5 sayısı yüklenir.

burda A register ına 0 degeri yüklenmiş olmuyor mu? 5 nerden çıktı anlamadım.

derslerin devamını bekliyorum eline sağlık.
Logged

ZX Spectrum 48K+ , Amiga 1200 , ZX Spectrum +2 , Amstrad 6128
---------------
7D9 Oyun Yarışması 2.si Board Soccer
7DX Oyun Yarışması 3.sü Run Baby Run
7DX 2013 Oyun Yarışması 3.sü Falcon Patrol
hades
Üye
****
Mesaj Sayısı: 332



Üyelik Bilgileri
« Yanıtla #3 : Ocak 01, 2009, 16:42:52 ÖS »

Hata düzeltildi ve konu güncelleştirildi.
« Son Düzenleme: Ocak 01, 2009, 20:27:54 ÖS Gönderen: hades » Logged
hades
Üye
****
Mesaj Sayısı: 332



Üyelik Bilgileri
« Yanıtla #4 : Ocak 03, 2009, 00:03:11 ÖÖ »

DERS 3 - SIÇRAMA VE GERİ DÖNÜŞ KOMUTLARI

Kaldığımız yerden devam ediyoruz. Sıçrama komutları iki bölüme ayrılır.
1- Mutlak sıçrama komutları,
2- Göreceli sıçrama komutları.

Hem mutlak sıçrama komutları, hem de göreceli sıçrama komutları kendi aralarında şartsız ve şartlı olarak ikiye ayrılır.

1 - MUTLAK SIÇRAMA KOMUTLARI
Mutlak sıçrama komutlarında hedef adresin kendisi yazılır. Bu komutlar işlev bakımından ikiye ayrılır. Birincisi CALL komutu, ikincisi JP komutudur. CALL komutu şöyle çalışır. Ana program çalışırken CALL komutuna sıra geldiğinde, program CALL komutuyla belirtilen adresteki başka bir programı çalıştırır ve program sonuna mutlaka olması gereken RET komutuyla ana programa geri döner. Ana programda CALL komutundan sonraki komut işletilir.
JP komutuyla ise program ilgili adrese sıçrar ve oradan çalışmaya devam eder.
CALL komutu örnek :

ld a,0
call renk
ld a,1
call renk
ld a,2
call renk
...
...
...

renk out (254),a
xor a
out (254),a
ret
...
...

JP komutu örnek :

ld hl,4000h
ld a,(hl)
jp devam
....
...
...
devam out (254),a
....
...

CALL ve JP komutlarında adres 0 ile 65535 arasında olabilir.
Mutlak sıçrama komutlarında HL,IX ve IY registerleride kullanılabilir. Bu komutlar JP (HL), JP (IX) ve JP (IY) dır.

2 - GÖRECELİ SIÇRAMA KOMUTLARI
Bu sıçrama komutlarında, hedef adresin kendisi değil, adrese olan uzaklık belirtilir. Bu uzaklık parametresi -geçen derste gördüğümüz "d:mesafe" ile gösterilir- 0-127 arasındaysa, şıçrama ileri yöndedir. 128-255 arasında ise geri yöndedir. Dolayısıyla bu komutlarla ancak program içerisinde kısa mesafelere sıçrayabilirsiniz.

Sapılacak adres gerideyse kaç bayt olduğu 256-d formülüyle bulunur. Programlarımızı yazarken etiket kullandığımız için kaç bayt ileri veya geri gittiğimiz program derlenirken hesaplanır. Eğer mesafe sınırlar dışındaysa derleyici hata verecektir.
Göreceli sıçrama komutu JR ile gösterilir ve Jump Relative'nin kısaltmasıdır. Eğer yazdığınız program kısa ve programı sürekli çalıştıracaksanız JR komutunu, uzunsa JP komutunu kullanabilirsiniz.

Örnek :
start ld a,0
loop1 ld b,1
...
...  Aradaki program 128 bayttan uzun olmamalıdır.
...
jr loop1


GERİ DÖNÜŞ KOMUTLARI :
Geri dönüş komutları ana programı bir kez çalıştırıp sonlandırmak için ve CALL ile sıçranılan alt programlardan ana programa dönüş için kullanılan komutlardır. Geri dönüş komutlaı da şartsız ve şartlı olarak ikiye ayrılır.
En çok kullanacağımız şartsız geri dönüş komutudur ve RET ile gösterilir. Return'un kısaltmasıdır.
RET komutuna benzer "RETI" ve "RETN" komutları vardır. "RETI" interrupttan geri dön, "RETN" Maskelenez İnterruptan geri dön demektir.

ŞARTLAR :

Şart dediğimiz durumlar, o an işlenen bir komuta göre "F" registerinin değişen bitlerini kontrol ederek öğrenilir. "F" (Flag) registerinin bitleri aşağıdaki gibi tanımlanmıştır.

7.bit : Sign (işaret) biti,
6.bit : Zero (sıfır) biti,
5.bit : Tanımsız,
4.bit : Half Carry biti,
3.bit : Tanımsız,
2.bit : P/V (Parity/Overflov) Eşlik/Taşma biti,
1.bit : A/N (Add/Subtract) Toplama(0)/Çıkartma(1) biti,
0.bit : C (Cary) Elde biti.

Bazı komutlar bu bitlerden birden fazlasını değiştirebilir.

ŞARTLI MUTLAK SIÇRAMA KOMUTLARI :

CALL Z,adres ; "Zero" biti "1" ise sıçra,
CALL NZ,adres ; "Zero" biti "0" ise sıçra,
CALL C,adres ; "Carry" biti "1" ise sıçra,
CALL NC,adres ; "Carry" biti "0" ise sıçra,
CALL P,adres ; "Sign" biti "1" (pozitif) ise sıçra,
CALL M,adres ; "Sign" biti "0" (negatif) ise sıçra,
CALL PE,adres ; "P/V" biti "1" ise çağır,
CALL PO,adres ; "P/V" biti "0" is çağır.

JP Z,adres
JP NZ,adres
JP C,adres
JP NC,adres
JP P,adres
JP M,adres
JP PE,adres
JP PO,adres

ŞARTLI GÖRECELİ SIÇRAMA KOMUTLARI :

JR Z,mesafe
JR NZ,mesafe
JR C,mesafe
JR NC,mesafe
DJNZ mesafe

DJNZ mesafe komutu özel olarak B registeri içindir. Açılımı "Decrement and Jump if Not Zero" dur. Yani B registerinin değerini bir azalt, registerin değeri "0" olmadıysa sıçra demektir.

ŞARTLI GERİ DÖNÜŞ KOMUTLARI :
Aynı şartlı sıçrama komutlarında olduğu gibi geri dönüşlerde de bazı şartlar kontrol edilebilir ve geri dönüş işlemi yapılabilir.

RET C
RET NC
RET Z
RET NZ
RET M
RET P
RET PE
RET PO

Bu konu oldukça önemlidir ve program içinde döngü yaparken bazı durumları kontrol için gereklidir.
« Son Düzenleme: Ocak 03, 2009, 00:15:21 ÖÖ Gönderen: hades » Logged
hades
Üye
****
Mesaj Sayısı: 332



Üyelik Bilgileri
« Yanıtla #5 : Ocak 03, 2009, 00:14:00 ÖÖ »

İLK PROGRAMIMIZI YAZIYORUZ.

İlk iki derste öğrendiklerimizi kullanarak basit bir program yazalım.
Programı çalıştırmak gibi bir amacımız yoktur. Sadece öğrendiklerimizi pekiştirmek içindir.

LD A,72 ---> Aküye 72 sayısını yükle.
LD HL,22528 --->HL registerine 22528 sayısını yükle
LD (HL),A ----> 22528 adresine Aküdeki sayıyı yükle
CALL yeni ----> "yeni" etiketli alt programa git
LD C,H ----> C registerine H registerindeki değeri yükle.
RET ----> Ana programdan çık.

yeni LD A,80 ---> Aküye 80 sayısını yükle
LD HL,22529 ----> HL registerine 22529 sayısını yükle
LD (HL),A ------> 22529 adresine Aküdeki sayıyı yükle
RET -----> Alt programdan ana programa geri dön.
Logged
Arda
Uzman
*****
Mesaj Sayısı: 2.326


I'm *the* guy from Argleton


Üyelik Bilgileri WWW
« Yanıtla #6 : Ocak 03, 2009, 23:36:27 ÖS »

Şartlı sıçrama komutlarına birkaç örnek de benden gelsin:
önce DJNZ, pratik bir opcode.

DJNZ, basic'deki for...next döngüsüne benzer.
Yukarıdaki örnekten alalım:

Kod:

        ld B,16    ; For b=0 to 16 gibi
loop1   
       
        ...        ; Buraya tekrar edecek kodu ekleyin
       

        DJNZ loop1


B'ye yüklediğiniz rakam kadar tur atacak bu program.

Tabiiki bu halde maksimum 255 tekrar yapılabilir. Daha fazla tekrar için şöyle bişey yapabilirsiniz:

Kod:
        LD BC, 9999 ; burada 9999 tur atılacak
                    ; 16 bitlik register çifti kullanarak (max.65535)
loop1

        ...         ;Tekrar edilecek kodunuzu tam buraya ekleyin
       
        DEC BC       
        LD A,B       
        OR C         
        JR NZ, loop1 
Logged

hades
Üye
****
Mesaj Sayısı: 332



Üyelik Bilgileri
« Yanıtla #7 : Ocak 04, 2009, 17:28:23 ÖS »

DERS 4 - ARİTMETİKSEL/MANTIKSAL KOMUTLAR :

1-ARİTMETİKSEL KOMUTLAR :

Adındanda anlaşılacağı üzere Z80 registerleriyle işlem yaparken 8 bitlik veya 16 bitlik toplama ve 8 bitlik çıkarma yapabiliriz.
Z80'de gerek toplama gerekse çıkartma işlemlerinde "C" (elde) biti kullanıp kullanmamamızı sağlayan komutlar vardır.
Aritmetik komutlarında çarpma ve bölme komutları yoktur.

8 bitlik toplam ve çıkartma komutları sadece Aküyle kullanılır. Yani sadece Aküyü kullanarak toplama/çıkartma yapabiliriz. Yapılan işlemin sonucu Aküde tutulur. 16 bitlik toplma işlemlerde HL, IX ve IY registerleri kullanılır ve sonuç hedef registerde tutulur. İşlemin sonucunda "Z,C,S,H,V" bitleri etkilenir.

-- TOPLAMA KOMUTLARI --

a) "C" biti (Elde biti) kullanılan toplama komutları:

a-1) 8 bitlik toplama komutları

ADC A,(HL) --> HL registerinde tutulan sayının gösterdiği adresin içeriği ile Akünün içeriği "C" biti kullanılar toplanır. Sonuç Aküde tutulur.

ADC A,(IX+d) ve ADC A,(IY+d) :  Yukarıdaki komut gibidir. Ancak IX ve IY registerlerinde tutulan sayıya "d" ile belirtilen sayı eklenerek bulunan yeni değerin gösterdiği adresin içeriği Aküye yüklenir.

ADC A,r --> Akü ile herhangi bir registerin içeriği "C" biti kullanılarak toplanır ve sonuç Aküde tutulur. "r" yerine A,B,C,D,E,H,L gelebilir.

ADC A,nn --> Akü ile 8 bitlik sabit bir sayı, "C" biti kullanılarak toplanır ve sonuç Aküde tutulur.

a-2)16 bitlik toplama komutları:

"C" biti kullanılan 16 bitlik toplama komutları sadece HL registeriyle kullanılır.

ADC HL,BC --> HL ile BC'nin içeriği "C" biti kullanılarak toplanır ve sonuç HL'de tutulur.
ADC HL,DE --> HL ile DE'nin içeriği "C" biti kullanılarak toplanır ve sonuç HL'de tutulur.
ADC HL,HL --> HL ile HL'nin içeriği "C" biti kullanılarak toplanır ve sonuç HL'de tutulur.
ADC HL,SP --> HL ile SP'nin içeriği "C" biti kullanılarak toplanır ve sonuç HL'de tutulur.

NOT : Bir register kendisiyle toplandığında registerdeki değer 2 ile çarpılmış olur.
NOT : "C" biti toplama sırasında sonucu etkiler. Etkilememesi için "C" bitinin sıfırlanması gerekir. "CCF" komutu "Clear Carry Flag" demektir ve "C" bitini "0" yapar.


b) "C" biti (Elde biti) kullanılmaya toplama komutları :

b-1) 8 bitlik komutlar:

Bu tip komutlarda "C" bitinin durumu dikkate alınmaz. İşlem yapılır ve sonuç Aküde tutulur.

ADD A,(HL)
ADD A,(IX+d)
ADD A,(IY+d)

ADD A,r --> "r" yerine A,B,C,D,E,H,L gelebilir.

ADD A,nn

b-2) 16 bitlik komutlar :

"C" bitinin durumu dikkate alınmaz, sonuç hedef registerde tutulur.
Hatırlatma : Bir komuttan sonra yazılan ilk parametre hedef, ikinci parametre kaynaktır.

ADD HL,BC
ADD HL,DE
ADD HL,HL
ADD HL,SP

ADD IX,BC
ADD IX,DE
ADD IX,IX
ADD IX,SP

ADD IY,BC
ADD IY,DE
ADD IY,IY
ADD IY,SP


-- ÇIKARTMA KOMUTLARI --

a) "C" biti (Elde biti) kullanılan komutlar:

a-1) 8 bitlik çıkartma komutları:

SBC A,(HL)
SBC A,(IX+d)
SBC A,(IY+d)

SBC A,r

SBC A,nn

a-2) 16 bitlik çıkartma komutları:

SBC HL,BC
SBC HL,DE
SBC HL,HL
SBC HL,SP


b) "C" biti (Elde biti) kulllanılmayan komutlar.

Bu kategoride sadece 8 bitlik komutlar mevcuttur.

SUB A,(HL)
SUB A,(IX+d)
SUB A,(IY+d)

SUB A,r

SUB A,nn

NOT : Çıkartma işleminde "C" biti sonucu etkiler. Etkilememesi için "C" bitinin set edilmesi gerekir. "SCF" komutu (Set Carry Flag) demektir ve "C" biti "1" yapar.


2 - MANTIKSAL KOMUTLAR :

Mantıksal komutlarla Aküdeki değer ile başka bir değer arasında bit düzeyinde AND (ve), OR (veya), XOR (özel veya) işlemi yapabiliriz.
Komutları görmeden önce bu işlemlerin nasıl olduğunu görelim.
Komutlar bit düzeyinde işlem yaptığı için hedef ile kaynak arasındaki etkileşim aynı numaralı bitler arasında olur.

a) "AND" işlemi:

AND işleminde bir birine karşılık gelen bitlerin her ikiside "1" ise hedef bit "1" olur. Diğer durumlarda hedef bit "0" değerini alır.

 0 AND 0 = 0
 0 AND 1 = 0
 1 AND 0 = 0
 1 AND 1 = 1

AND komutuyla istediğimiz bitleri "0" yapabiliriz. AND işlemi bit düzeyinde çarpma işlemidir.

AND (HL)
AND (IX+d)
AND (IY+d)

AND r --> "r" yerine A,B,C,D,E,H,L gelebilir. Akü ile kaynak register arasında AND işlemi yapılır.

AND nn --> Akü ile 8 bitlik sabit sayı arasında AND işlemi yapılır.

ÖRNEK :

Aküdeki değeri ikili sistemdem gösterelim ve
%11001011 (203) olsun. Kaynak ise;
%00101101 (45) olsun. AND işleminin sonucu;
---------
%00001001 (9) olur

Akünün herhangi bir bitini "0" yapmak için, 255-bitin sayısal değeri=, AND komutunun parametresi olarak kullanılır. Sonuç Aküde yer alır.
Yukarıdaki örnekten devam edelim ve 3. bitini (normalde "1") "0" yapalım.
3. bitin sayısal değeri 8'dir. (ilk dersimizi hatırlayın). Sayımız 255-8=247 olur ve ikili sistemde %11110111 ile gösterilir.

%11001011 (203)
%11110111 (247)
---------
%11000011 (195)

Gördüğünüz gibi 3. biti "0" yaptık. Eğer birden fazla biti "0" yapmak gerekiyorsa, ilgili bitlerin sayısal değerlerini toplarız ve 255 ten çıkartırız.


b) "OR" işlemi:

OR işleminde bir birine karşılık gelen bitlerin her ikiside "0" ise hedef bit "0" olur. Diğer durumlarda hedef bit "1" değerini alır.

 0 OR 0 = 0
 0 OR 1 = 1
 1 OR 0 = 1
 1 OR 1 = 1

OR komutuyla istediğimiz bitleri "1" yapabiliriz. OR işlemi bit düzeyinde toplama işlemidir.

OR (HL)
OR (IX+d)
OR (IY+d)

OR r --> "r" yerine A,B,C,D,E,H,L gelebilir. Akü ile kaynak register arasında OR işlemi yapılır.

OR nn --> Akü ile 8 bitlik sabit sayı arasında OR işlemi yapılır.

ÖRNEK :

Aküdeki değeri ikili sistemdem gösterelim ve
%11001011 (203) olsun. Kaynak ise;
%00101101 (45) olsun. OR işleminin sonucu;
---------
%11101111 (239) olur

Akünün herhangi bir bitini "1" yapmak için, ilgili bitin sayısal değeri, OR komutunun parametresi olarak kullanılır. Sonuç Aküde yer alır.
Yukarıdaki örnekten devam edelim ve 5. bitini (normalde "0") "1" yapalım.
5. bitin sayısal değeri 32'dir. (ilk dersimizi hatırlayın). Sayımız 32 olur ve ikili sistemde %00100000 ile gösterilir.

%11001011 (203)
%00100000 (32)
---------
%11101011 (235)

Gördüğünüz gibi 5. biti "1" yaptık. Eğer birden fazla biti "1" yapmak gerekiyorsa, ilgili bitlerin sayısal değerlerini toplarız ve OR komutunun parametresi olarak kullanırız.

c) "XOR" işlemi:

XOR işleminde bir birine karşılık gelen bitlerin her ikiside aynı ise hedef bit "0" olur. Diğer durumlarda hedef bit "1" değerini alır.

 0 XOR 0 = 0
 0 XOR 1 = 1
 1 XOR 0 = 1
 1 XOR 1 = 0

XOR komutunu kullanarak herhangi bir bitin "0" ve "1" arasında dönüşümünü sağlayabiliriz.

XOR (HL)
XOR (IX+d)
XOR (IY+d)

XOR r --> "r" yerine A,B,C,D,E,H,L gelebilir. XOR A komutu Aküyü sıfırlar.

XOR nn --> Akü ile 8 bitlik sabit sayı arasında XOR işlemi yapılır.

ÖRNEK :

Aküdeki değeri ikili sistemdem gösterelim ve
%11001011 (203) olsun. Kaynak ise;
%00101101 (45) olsun. XOR işleminin sonucu;
---------
%11100110 (230) olur


Aküdeki değerin 7. bitini "1" iken "0", "0" iken "1" yapalım. Hangi bitin durumunu değiştireceksek Akü ile o bitin sayısal değeri arasında XOR işlemi yaparız.

%11001011 (203) Aküdeki eski değer.
%10000000 (128) 7. bitin değeri.
---------
%01001011 (75) Aküdeki yeni değer.

Gördüğünüz gibi diğer bitlere dokunmadan 7. bitin durumunu değiştirdik. "1" iken "0" oldu. Aynı işlemi tekrar edelim.

%01001011 (75) Aküdeki eski değer.
%10000000 (128) 7. bitin değeri.
---------
%11001011 (203) Aküdeki yeni değer.

Diğer bitlere dokunmadan 7. biti "0" durumundan "1" durumuna getirdik.
XOR komutunu istediğimiz bit(ler) için "0/1" anahtarı gibi kullanabiliriz.

Unuymayalım, XOR komutunda karşılıklı gelen bitlerin durumları aynıysa sonuç "0", farklıysa "1" olur.


NOT : AND, OR ve XOR komutları sadece Aküyle kullanılır. Yapılan işlem sonucunda Aküdeki değer değişir. Ayrıca "Flag" registerindeki bitler etkilenir.


(Yazıda hatalı yerler varsa bildirin, kontrol edeyim.)
Logged
hades
Üye
****
Mesaj Sayısı: 332



Üyelik Bilgileri
« Yanıtla #8 : Ocak 17, 2009, 00:25:55 ÖÖ »

Kısa bir aradan sonra derslere devam ediyoruz. Ancak sıradaki derse geçmeden önce ilk mesaja kısa bir ek yaptım ve bu ek için aşağıdaki bilgileri 2. DERS "yükleme komutları" içinde ele almamız uygun olacaktır.

YIĞIN KOMUTLARI :

Yığın dediğimiz yer, bir mikroişlemcinin çalışması sırasında bazı registerlerin değerlerinin ve alt rutin çağırma komutlarında geri dönüş adresinin saklandığı bir RAM bölgesidir. Bu adresi Z80 de LD SP,Adres ile değiştirmek mümkündür.
Registerler yığına tek olarak değil register çifti olarak kaydedilir.

PUSH rp ile register çifti yığına atılır, POP rp ile yığından geri alınır. rp yerine AF,BC,DE,HL,IX,IY gelebilir.
Programda PUSH ve POP komutlarını kullanırken dikkatli olmak gerekir. Özellikle iç içe olan döngülerde kullanılan PUSH/POP komutları programın yanlış çalışmasına yol açabilir.
Yığın aynı zamanda geri dönüş adresini tuttuğu için alt rutinlerde daha fazla dikkat etmek gerekir.

.....
.....
29997 CALL ALTRUTİN (32000)
30000 LD A,0
.....
.....


-ALT RUTİN-
32000 PUSH BC
.......
.......
RET

Yukarıdaki örnek hatalıdır. Ana programdaki CALL komutunun adresi 29997 olsun ve CALL 32000 ile alt rutine gidilsin. İşlemci CALL komutunu gördüğünde, bir sonraki komutun (örnekte LD A,0) adresini (30000) yığına atar ve alt rutine gider. Alt rutinde ise PUSH BC ile BC'deki değer de yığına atılmıştır ve bu 0 ile 65535 arasında herhangi bir değer olabilir. Alt rutindeki işler yapılıp RET komutu işlendiğinde, işlemci yığından iki byte alıp bunu geri dönüş adresi olarak kullanacak ve ana programa kaldığı yerden devam edecektir. Oysa örneğimizde geri dönüş adresi olarak yığından 30000 değil, BC deki değer okunacaktır. Bu hatanın önüne geçmenin iki yolu vardır. İlki CALL komutundan önce ilgili registerleri yığına atmak ve CALL komutundan sonra bu registerleri yığından geri almaktır. Diğeri ise alt rutinde ilk iş olarak registerleri yığına atmak, RET komutundan hemen önce ilgili registerleri yığından geri almaktır.

......
PUSH ..
PUSH ..
CALL altrutin
POP ..
POP ..
......

veya

......
CALL altrutin
......

altrutin
PUSH ..
PUSH ..
.....
.....
POP ..
POP ..
RET

Kesin kural : Program içinde ne kadar PUSH komutu varsa o kadar POP komutu olmalıdır.

Bir başka konu ise yığına en son atılan değer, yığından ilk olarak alınır. Bu işlemi üst üste koyulan tuğlalar gibi düşünebilirsiniz. Üst üste 5 tuğla koyduğunuzda alt sıralardakini alamazsınız. Altlardakini almak için en üsten itibaren tuğlaları indirmeniz gerekmektedir. Bu nedenle PUSH/POP komutlarında register sıralamanıza dikkat etmelisiniz.

PUSH BC
PUSH HL
....
....
....
POP HL
....
....
POP BC

Gördüğünüz gibi en son HL'yi yığına attık. Yığındaki en son değer HL'nin değeridir. Arada yapılan işlemlerden sonra yığında bulunan değeri geri alıp kullanacaksak bunu POP HL ile yapmalıyız. POP HL yerine POP BC yazarsak, yığından geri alınan değer BC'ye yüklenecektir.
;------------------------------------------------------------------------------
DERS 4 : ARTTIRMA VE AZALTMA KOMUTLARI

Z80'de register ve adresteki değeri arttırmak için arttırma ve azaltma komutları vardır. Azaltma komutu DEC’tir ve decrement’in kısaltmasıdır. Aynı şekilde arttırma komutu INC’tir ve increment’in kısaltmasıdır.

DEC komutu ile herhangi bir registerin veya adresin içeriği 1 azaltılır. Registerin veya adresin içeriği 0 iken azaltma yapılırsa yeni değer 255 veya 65535 olur.
Aynı şekilde INC komutu ile herhangi bir registerin veya adresin içeriği 1 arttırılır. Registerin veya adresin içeriği 255 veya 65535 iken arttırma yapılırsa yeni değer 0 olur.

Azaltma komutları :

DEC A
DEC B
DEC C
DEC D
DEC E
DEC H
DEC L
DEC BC
DEC DE
DEC HL
DEC IX
DEC IY
DEC SP
DEC (HL)
DEC (IX+d)
DEC (IY+d)

Arttırma komutları : Yukarıdaki listedeki DEC’lerin yerine INC getirilecek.

NOT : Bazı komutlarda (IX+d) ve (IY+d) gibi ifadeler bulunmaktadır. Bu yazım şekli IX veya IY registerinde tutulan değere “d” kadar bir sayı ekleneceğini belirtir. “d” değeri (+0...+127) veya (-0...-128) arasında bir sayı olabilir.
IX’de 5040h olsun, INC (IX+10h) ile 5040h+10h=5050h adresinin içeriği 1 arttırılır. Aynı şekilde DEC (IX-40h) ile 5040h-40h=5000h adresinin içeriği 1 azaltılır.


DERS 5 : KAYDIRMA / DÖNDÜRME KOMUTLARI :

Z80 kaydırma ve döndürme komutları bakımından epeyce zengindir. Bu komutları açıklamalı olarak aşağıda alfabetik sıraya göre veriyorum.

DÖNDÜRME KOMUTLARI :

RL r : Sola döndür.
-------------------
Carry biti kullanılarak 9 bitlik bir döndürme işlemi yapılır. İlgili registerdeki / adresteki bütün bitler bir sola kayar. 7. bit Carry’e, Carry’de daha önce bulunan değer 0. bite yüklenir.
Kullanılan registerler : A,B,C,D,E,H,L,(HL),(IX+d),(IY+d)

RLA : Aküyü sola döndür.
------------------------
RL r komutunun sadece A registeri için kullanılan bir şeklidir. Görevi aynıdır. Yani RL A yerine RLA kullanabilirsiniz. RL A komutu 2 byte iken RLA 1 byte’tır.

RLC r : Carry’i kullanmadan sola döndür.
----------------------------------------
RL r gibidir. Ancak döndürme işlemi 8 bitliktir. Registerdeki / adresteki bitler bir sola kayar. 7. bit Carry’e ve 0. bite yüklenir. Carry’de daha önce bulunan değer işleme konmaz.
Kullanılan registerler : A,B,C,D,E,H,L,(HL),(IX+d),(IY+d)

RLCA : Aküyü carry’i kullanmadan sola döndür.
---------------------------------------------
RLC r komutunun sadece A registeri için kullanılan bir şeklidir. Görevi aynıdır. Yani RLC A yerine RLCA kullanabilirsiniz. RL A komutu 2 byte iken RLA 1 byte’tır.

RLD : Sola ondalık döndür. (Rotate Left Decimal)
------------------------------------------------
Bu komut ile (HL)’nin (HL registerinin gösterdiği adresin içeriği) üst 4 biti (7..4) Akünün alt 4 bitine (3..0), (HL)’nin alt 4 biti (3..0) (HL)’nin üst 4 bitine (7..4), Aküde daha önce bulunan alt 4 bit (3..0) (HL)’nin alt 4 bitine (3..0) kopyalanır.


RR r : Sağa döndür.
-------------------
Carry biti kullanılarak 9 bitlik bir döndürme işlemi yapılır. İlgili registerdeki / adresteki bütün bitler bir sağa kayar. 0. bit Carry’e, Carry’de daha önce bulunan değer 7. bite yüklenir.
Kullanılan registerler : A,B,C,D,E,H,L,(HL),(IX+d),(IY+d)

RRA : Aküyü sağa döndür.
------------------------
RR r komutunun sadece A registeri için kullanılan bir şeklidir. Görevi aynıdır. Yani RR A yerine RRA kullanabilirsiniz. RR A komutu 2 byte iken RRA 1 byte’tır.

RRC r : Carry’i kullanmadan sağa döndür.
----------------------------------------
RR r gibidir. Ancak döndürme işlemi 8 bitliktir. Registerdeki / adresteki bitler bir sağa kayar. 0. bit Carry’e ve 7. bite yüklenir. Carry’de daha önce bulunan değer işleme konmaz.
Kullanılan registerler : A,B,C,D,E,H,L,(HL),(IX+d),(IY+d)

RRCA : Aküyü carry’i kullanmadan sağa döndür.
---------------------------------------------
RRC r komutunun sadece A registeri için kullanılan bir şeklidir. Görevi aynıdır. Yani RRC A yerine RRCA kullanabilirsiniz. RR A komutu 2 byte iken RRA 1 byte’tır.

RRD : Sağa ondalık döndür. (Rotate Right Decimal)
------------------------------------------------
Bu komut ile (HL)’nin (HL registerinin gösterdiği adresin içeriği) alt 4 biti (3..0) Akünün alt 4 bitine (3..0), (HL)’nin üst 4 biti (7..4) (HL)’nin alt 4 bitine (3..0), Aküde daha önce bulunan alt 4 bit (3..0) (HL)’nin üst 4 bitine (7..4) kopyalanır.

KAYDIRMA KOMUTLARI :

SLA r : Sola aritmetik kaydır.
------------------------------
İlgili registerdeki / adresteki bitler bir sola kayar. 7. bit Carry’e yüklenirken, 0. bite 0 yüklenir. Bu komut ile registerdeki/adresteki değer 2 ile çarpılmış olur.
Kullanılan registerler : A,B,C,D,E,H,L,(HL),(IX+d),(IY+d)

SRA r : Sağa aritmetik kaydır.
------------------------------
İlgili registerdeki / adresteki bitler bir sağa kayar. 0. bit Carry’e yüklenirken, 7. bit tekrar 7. bite yüklenir. Yani 7. bitin içeriği değşmez.
Kullanılan registerler : A,B,C,D,E,H,L,(HL),(IX+d),(IY+d)

SRL : Sağa mantıksal kaydır.
----------------------------
İlgili registerdeki / adresteki bitler bir sola kayar. 0. bit Carry’e yüklenirken, 7. bite 0 yüklenir. Bu komut ile registerdeki/adresteki değer 2’ye bölünmüş olur.
Kullanılan registerler : A,B,C,D,E,H,L,(HL),(IX+d),(IY+d)

« Son Düzenleme: Ocak 17, 2009, 23:14:22 ÖS Gönderen: hades » Logged
nightlord
Uzman
*****
Mesaj Sayısı: 558



Üyelik Bilgileri WWW
« Yanıtla #9 : Ağustos 11, 2010, 20:18:37 ÖS »

bu dersler acayip oz ve aciklayici olmus Hades. Helal olsun sana

Logged
blackturk
Uzman
*****
Mesaj Sayısı: 1.144



Üyelik Bilgileri
« Yanıtla #10 : Kasım 03, 2015, 20:01:04 ÖS »

   Güzel bir hoooort yapıyım.Birde burdaki z80 assembly dersi için bir ekleme yaparak devam edelim.

    Aritmatiksel komut  "CPL" Akümalatörü 1'e tümleyeni işlemin yapıyor.0'ları  1'e  ve 1'leri  0'a dönüştürüyor.

         Accc-> %00100011--->sonuc---->%11011100 olur

             
 
Logged

A1200 | APOLLO 1240 32 MB | CNET PCMCIA | SYSINFO SPEED TEST 30 MIPS
SM1,SEGA MEGA CD,SM2,SMS II,Sega Saturn Mod ve AR 4MB,PSX Mod ve Mpeg ,PSX2 ,SNES ,ATARI 800XL,SPECTRUM 128K +2,YAMAHA CX5M MSX,ATARI 520 STFM,1040 STF,C64,C128,1541 II,1571,RAM 1764 ,A500,A500+,A600,A590,IDE68k,2X1084S,1084P
Sayfa: [1]   Yukarı git
Yazdır
Gitmek istediğiniz yer: