8086 Kaydedici Adresleme:
Adından anlaşılacağı gibi kaydediciden kaydediciye yapılan işlemlerde bu adresleme modları kullanılır. En hızlı adresleme modu’dur, çünkü işlem hafızada değil işlemcinin içinde gerçekleşir.
Genel amaçlı ve indeks kaydedicilerde kaydedici adresleme modları:
mov ax, bx ; BX teki değeri AX’e kopyalar
mov dl, al ; AL teki değeri DL’ye kopyalar
mov si, dx ; DX teki değeri SI’ya kopyalar
mov sp, bp ; SP deki değeri BP’ye kopyalar
mov dh, cl ; CL deki değeri DH’a kopyalar
mov ax, ax ; Bu da doğru bir kullanımdır!
Kaydedici adreslemede en çok dikkat etmeniz gereken husus hedef ve kaynağın boyutlarıdır. Örneğin 16 bitlik bir kaydediciden 8 bitlik bir kaydediciye taşıma yapılamaz!
mov al, bx ;yanlış kullanım, derleme anında assembler hata verir.
Küçük boyuttaki kaynaktan büyük boyuttaki hedefe de kopyalama yapılamaz.
mov cx, al ; Yanlış kullanım, AL’ile CX eşit boyutta değil.
Bunlara ek olarak segment kaydedicilerinin kullanımında dikkat edilmesi gereken noktalar vardır.
1- Segment kaydedicileri arasında bir transfer işlemi ancak genel amaçlı bir kaydedici vasıtasıyla yapılabilir.
mov ds,cs ; doğru kullanılmayan segment kaydedicisi şeklinde assembler hata verir!
Bu işi yapmak için,
mov ax,cs
mov ds,ax
komut satırları kullanılabilir.
2- CS ve IP kaydedicilerinin değeri kaydedici adresleme ile değiştirilemez
mov cs, ax ; kaynak genel amaçlı kaydedici olmasına rağmen bu işlem mümkün değildir!
Segment kaydedicileri programın icrası aşamasında hafızanın segment olarak adlandırılan bölümlerinin adreslerini tuttuklarından, bu kaydedicileri verilerinizi saklamak veya taşımak için kullanmanızı tavsiye etmem, kullanılmamalıdırlar. Bunun yerine genel amaçlı kaydedicileri kullanmanız daha uygun olur.
8086 Hafıza Adresleme Modları
a- Acil Adresleme ( Immediate Addressing )
Herhangi bir genel amaçlı veya indeks kaydedicisine doğrudan bir değer yükleye bilirsiniz. Yüklenecek olan veri kod segmentten alınacağından bu tür kullanımları şahsen ben pek tavsiye etmem. İyi bir program organizasyonu için, veriler hafızanın ayrı bir bölümünde (mesela data segmentte) değişkenler veya sabitler olarak belirtilmelidir.
mov al, 17 ; AL’ye 11h yüklenir.
b- Direkt Adresleme (Displacement Only Addressing )
Acil adreslemenin doğru kullanılmış şeklidir. Bu adreslemede segment:ofset adresi kullanılarak hafızaya erişilir.
mov al, ds:12 ; ds:000C adresinden 1 byte AL’ye kopyalanır.
mov ds:12, al ; AL’nin içeriği ds:000C adresine kopyalanır.
mov ax, ds:12 ; ds:000C adresinden 2 byte AX’ye kopyalanır.
mov ds:12, ax ; AX’nin içeriği ds:000C adresinden itibaren kopyalanır (2 byte)
Aslında kaynak kod hazırlanırken genelde bu şekilde bir kod yazımı yapılmaz. Değişkenler ve sabitler sembolik kelimelerle ifade edildiğinden buna gerek yoktur. Ne var ki debugger programlarında da sembolik değişken isimlerini değil adresleri görürüz. Aşağıdaki kod parçasını inceleyin;
.data
sayi1 db 5
.code
mov ax, @data
mov ds, ax
mov al, sayi ; 5 değerini al’ye yükler.
mov al, ds:0000 ; aynı işi yapar yani 5’i AL’ye yükler.
; veriler tanımlanırken sayi1 db 5 şeklinde değil de
; sadece db 5 yazılsaydı, bu komutu kullanmak zorunda kalırdık.
c- Kaydedici Dolaylı Adresleme ( Register Indirect Addressing )
Adının kaydedici olduğuna aldanmayın. Burada operand olarak kullanılan kaydedici köşeli parantez içine alınır ve bu andan itibaren bir offset adresi oluverir.
mov al, [bx] ; hafızadan AL’ye 1 byte taşınır. Alınacak verinin offset adresi BX’in değeridir.
mov al, [bx]
mov al, [si]
mov al, [di]
mov al, [bp]
Yukarıdaki 4 örnekte AL’ye kopyalanacak verilerin offset adresleri ilgili kaydedicinin içindeki değerdir. Segment adresleri ise ilk üçünün DS sonuncusunun SS’dir. BP indeks kaydedicisi yalnız başına hafıza adreslemede kullanılırsa, daima stack segmentin (SS) offset adreslerini gösterir. Fakat BP kaydedicisi de dahil olmak üzere bu adresleme segment kaydedicileri de belirtilerek yapılırsa, o zaman ilgili segment:offset adresine erişilmiş olunur.
BX=0000, BP=0001, SI=0002, DI=0003 olduğunu varsayalım;
mov al, cs:[bx] ; AL’ye CS:0000’dan kopyalama yapılır
mov al, [bx] ; AL’ye DS:0000’dan kopyalama yapılır
mov al, ds:[bp] ; AL’ye DS:0001’den kopyalama yapılır
mov al, [bp] ; AL’ye SS:0001’den kopyalama yapılır
mov al, ss:[si] ; AL’ye SS:0002’den kopyalama yapılır
mov al, [si] ; AL’ye DS:0002’den kopyalama yapılır
mov al, es:[di] ; AL’ye ES:0003’den kopyalama yapılır
mov al, [di] ; AL’ye DS:0002’dan kopyalama yapılır
d- İndeksli adresleme ( Indexed Addressing )
Kaydedici dolaylı adreslemenin operandına sabit bir değer eklenmiş halidir.
Kullanım şekli;
mov al, disp[bx]
mov al, disp[bp]
mov al, disp[si]
mov al, disp[di]
Not : disp kısaltması İngilizcede displacement kelimesinin karşılığıdır. Buradaki anlamı ise referans alınan ofset adresidir. Komut setlerinde adresleme modları açıklanırken disp veya mem kısaltması ile çok sık karşılaşacağınızdan, komutları yazarken İngilizce ifadeler kullanmak durumunda kaldım.
Mesela BX=2000h olsun, mov dl, 20h[bx] şeklinde bir komut kullanıldığında, DS:2020h adresindeki 1 byte’lık değer dl’ye kopyalanacaktır. Aynı şekilde BP=3030h olduğunu varsayalım, mov dh,1020h[bp] gibi bir komut ile, SS:4050h adresindeki 1 byte’lık değer dh’a kopyalanır.
Bu adresleme modunda da BP segment kaydedicisi daima SS’in ofsetlerini gösterir. Fakat kaydedici dolaylı adreslemede de olduğu gibi bizzat segment kaydedicisinide belirterek bu adresleme modunu kullanabiliriz. Bu durumda ofset adresleri komutta belirtilen segmentin ofseti olur.
mov al, ss:disp[bx] ; BX normalde DS’nin ofsetlerini gösterirken burada SS’in ofseti olmuş.
mov al, es:disp[bp] ; BP normalde SS’nin ofsetlerini gösterirken burada ES’in ofseti olmuş.
mov al, cs:disp[si] ; SI normalde DS’nin ofsetlerini gösterirken burada CS’in ofseti olmuş.
mov al, ss:disp[di] ; DI normalde DS’nin ofsetlerini gösterirken burada SS’in ofseti olmuş.
e- Taban İndeksli adresleme ( Based Indexed Addressing )
Bu adresleme modu da kaydedici dolaylı adreslemeye çok benzer. Kullanım formatı aşağıdaki gibidir;
mov al, [bx][si]
mov al, [bx][di]
mov al, [bp][si]
mov al, [bp][di]
BX’in 0500h SI’nın 0360h olduğunu varsayalım,
mov al,[bx][si]
gibi bir komut işlenince AL’ye kopyalanacak veri DS:0860 adresinden alınır.
Aynı şekilde;
BP=1598h DI=1004 ve mov ax,[bp+di] gibi bir komut işleniyorsa; AX, SS:259Ch ve SS:259Dh adreslerindeki veri ile yüklenir.
SI ve DI kaydedicileri için Intel’in özel komutları vardır, bu yüzden bu kaydediciler genellikle programlamada indeks değerlerini tutar, arttırır veya azaltırlar.
f- Taban İndeksli artı direkt adresleme (Based Indexed Plus Displacement Addressing)
Bu adresleme modu taban indeksli adreslemeye 8 yada 16 bitlik sabit bir değerin eklenmiş halidir.
mov al, disp[bx][si]
mov al, disp[bx+di]
mov al, [bp+si+disp]
mov al, [bp][di][disp]
BP = 1000h, BX= 2000h, SI= 0120h, DI = 5 olduğunu varsayalım.
mov al,10h[bx+si] ; AL’ye DS:2130 adresindeki veri yüklenir
mov ch,125h[bp+di] ; CH’a SS:112A adresindeki veri yüklenir
mov bx,cs:2[bx][di] ; CS:2007 adresinden itibaten 2 byte’lık veri yüklenir
TASM ve MASM ‘ın adresleme modları için esnekliği.
TASM ve MASM assembler’ları indeksli, taban indeksli, ve taban indeksli artı direkt adresleme için değişik yazım şekillerini desteklerler;
İndeksli adresleme için;
disp[bx] = [bx][disp] = [bx+disp] = [disp][bx] = [disp+bx]
Taban indeksli adresleme için;
[bx][si] = [bx+si] = [si][bx] = [si+bx] ;
Taban İndeksli artı direkt adresleme için;
disp[bx][si] = disp[bx+si] = [disp+bx+si] = [disp+bx][si] = disp[si][bx] = [disp+si][bx] = [disp+si+bx] = [si+disp+bx] = [bx+disp+si]
Yukarıda yazılan bu 3 adresleme modundaki operandlar aynı işi yaparlar. MASM ve TASM "[ ]" sembollerine "+" operatörü gibi davranır. ( disp[bx][si] = disp[bx+si] örneğinde olduğu gibi )
8086 Adresleme Hafıza Adresleme Modlarını Hatırlamak İçin Kolay Bir Yol:
8086 işlemcisi için toplam 17 adet adresleme modu mevcuttur. Bunlar disp, [bx], [bp], [si], [di], disp[bx], disp[bp], disp[si], disp[di], [bx][si], [bx][di], [bp][si], [bp][di], disp[bx][si], disp [bx][di], disp[bp][si], and disp[bp][di] adresleme modlarıdır. Aşağıdaki şekil, bu 17 adresleme modunu ezberlemeniz yerine kolayca hatırlamanıza yardımcı olacaktır.
Adından anlaşılacağı gibi kaydediciden kaydediciye yapılan işlemlerde bu adresleme modları kullanılır. En hızlı adresleme modu’dur, çünkü işlem hafızada değil işlemcinin içinde gerçekleşir.
Genel amaçlı ve indeks kaydedicilerde kaydedici adresleme modları:
mov ax, bx ; BX teki değeri AX’e kopyalar
mov dl, al ; AL teki değeri DL’ye kopyalar
mov si, dx ; DX teki değeri SI’ya kopyalar
mov sp, bp ; SP deki değeri BP’ye kopyalar
mov dh, cl ; CL deki değeri DH’a kopyalar
mov ax, ax ; Bu da doğru bir kullanımdır!
Kaydedici adreslemede en çok dikkat etmeniz gereken husus hedef ve kaynağın boyutlarıdır. Örneğin 16 bitlik bir kaydediciden 8 bitlik bir kaydediciye taşıma yapılamaz!
mov al, bx ;yanlış kullanım, derleme anında assembler hata verir.
Küçük boyuttaki kaynaktan büyük boyuttaki hedefe de kopyalama yapılamaz.
mov cx, al ; Yanlış kullanım, AL’ile CX eşit boyutta değil.
Bunlara ek olarak segment kaydedicilerinin kullanımında dikkat edilmesi gereken noktalar vardır.
1- Segment kaydedicileri arasında bir transfer işlemi ancak genel amaçlı bir kaydedici vasıtasıyla yapılabilir.
mov ds,cs ; doğru kullanılmayan segment kaydedicisi şeklinde assembler hata verir!
Bu işi yapmak için,
mov ax,cs
mov ds,ax
komut satırları kullanılabilir.
2- CS ve IP kaydedicilerinin değeri kaydedici adresleme ile değiştirilemez
mov cs, ax ; kaynak genel amaçlı kaydedici olmasına rağmen bu işlem mümkün değildir!
Segment kaydedicileri programın icrası aşamasında hafızanın segment olarak adlandırılan bölümlerinin adreslerini tuttuklarından, bu kaydedicileri verilerinizi saklamak veya taşımak için kullanmanızı tavsiye etmem, kullanılmamalıdırlar. Bunun yerine genel amaçlı kaydedicileri kullanmanız daha uygun olur.
8086 Hafıza Adresleme Modları
a- Acil Adresleme ( Immediate Addressing )
Herhangi bir genel amaçlı veya indeks kaydedicisine doğrudan bir değer yükleye bilirsiniz. Yüklenecek olan veri kod segmentten alınacağından bu tür kullanımları şahsen ben pek tavsiye etmem. İyi bir program organizasyonu için, veriler hafızanın ayrı bir bölümünde (mesela data segmentte) değişkenler veya sabitler olarak belirtilmelidir.
mov al, 17 ; AL’ye 11h yüklenir.
b- Direkt Adresleme (Displacement Only Addressing )
Acil adreslemenin doğru kullanılmış şeklidir. Bu adreslemede segment:ofset adresi kullanılarak hafızaya erişilir.
mov al, ds:12 ; ds:000C adresinden 1 byte AL’ye kopyalanır.
mov ds:12, al ; AL’nin içeriği ds:000C adresine kopyalanır.
mov ax, ds:12 ; ds:000C adresinden 2 byte AX’ye kopyalanır.
mov ds:12, ax ; AX’nin içeriği ds:000C adresinden itibaren kopyalanır (2 byte)
Aslında kaynak kod hazırlanırken genelde bu şekilde bir kod yazımı yapılmaz. Değişkenler ve sabitler sembolik kelimelerle ifade edildiğinden buna gerek yoktur. Ne var ki debugger programlarında da sembolik değişken isimlerini değil adresleri görürüz. Aşağıdaki kod parçasını inceleyin;
.data
sayi1 db 5
.code
mov ax, @data
mov ds, ax
mov al, sayi ; 5 değerini al’ye yükler.
mov al, ds:0000 ; aynı işi yapar yani 5’i AL’ye yükler.
; veriler tanımlanırken sayi1 db 5 şeklinde değil de
; sadece db 5 yazılsaydı, bu komutu kullanmak zorunda kalırdık.
c- Kaydedici Dolaylı Adresleme ( Register Indirect Addressing )
Adının kaydedici olduğuna aldanmayın. Burada operand olarak kullanılan kaydedici köşeli parantez içine alınır ve bu andan itibaren bir offset adresi oluverir.
mov al, [bx] ; hafızadan AL’ye 1 byte taşınır. Alınacak verinin offset adresi BX’in değeridir.
mov al, [bx]
mov al, [si]
mov al, [di]
mov al, [bp]
Yukarıdaki 4 örnekte AL’ye kopyalanacak verilerin offset adresleri ilgili kaydedicinin içindeki değerdir. Segment adresleri ise ilk üçünün DS sonuncusunun SS’dir. BP indeks kaydedicisi yalnız başına hafıza adreslemede kullanılırsa, daima stack segmentin (SS) offset adreslerini gösterir. Fakat BP kaydedicisi de dahil olmak üzere bu adresleme segment kaydedicileri de belirtilerek yapılırsa, o zaman ilgili segment:offset adresine erişilmiş olunur.
BX=0000, BP=0001, SI=0002, DI=0003 olduğunu varsayalım;
mov al, cs:[bx] ; AL’ye CS:0000’dan kopyalama yapılır
mov al, [bx] ; AL’ye DS:0000’dan kopyalama yapılır
mov al, ds:[bp] ; AL’ye DS:0001’den kopyalama yapılır
mov al, [bp] ; AL’ye SS:0001’den kopyalama yapılır
mov al, ss:[si] ; AL’ye SS:0002’den kopyalama yapılır
mov al, [si] ; AL’ye DS:0002’den kopyalama yapılır
mov al, es:[di] ; AL’ye ES:0003’den kopyalama yapılır
mov al, [di] ; AL’ye DS:0002’dan kopyalama yapılır
d- İndeksli adresleme ( Indexed Addressing )
Kaydedici dolaylı adreslemenin operandına sabit bir değer eklenmiş halidir.
Kullanım şekli;
mov al, disp[bx]
mov al, disp[bp]
mov al, disp[si]
mov al, disp[di]
Not : disp kısaltması İngilizcede displacement kelimesinin karşılığıdır. Buradaki anlamı ise referans alınan ofset adresidir. Komut setlerinde adresleme modları açıklanırken disp veya mem kısaltması ile çok sık karşılaşacağınızdan, komutları yazarken İngilizce ifadeler kullanmak durumunda kaldım.
Mesela BX=2000h olsun, mov dl, 20h[bx] şeklinde bir komut kullanıldığında, DS:2020h adresindeki 1 byte’lık değer dl’ye kopyalanacaktır. Aynı şekilde BP=3030h olduğunu varsayalım, mov dh,1020h[bp] gibi bir komut ile, SS:4050h adresindeki 1 byte’lık değer dh’a kopyalanır.
Bu adresleme modunda da BP segment kaydedicisi daima SS’in ofsetlerini gösterir. Fakat kaydedici dolaylı adreslemede de olduğu gibi bizzat segment kaydedicisinide belirterek bu adresleme modunu kullanabiliriz. Bu durumda ofset adresleri komutta belirtilen segmentin ofseti olur.
mov al, ss:disp[bx] ; BX normalde DS’nin ofsetlerini gösterirken burada SS’in ofseti olmuş.
mov al, es:disp[bp] ; BP normalde SS’nin ofsetlerini gösterirken burada ES’in ofseti olmuş.
mov al, cs:disp[si] ; SI normalde DS’nin ofsetlerini gösterirken burada CS’in ofseti olmuş.
mov al, ss:disp[di] ; DI normalde DS’nin ofsetlerini gösterirken burada SS’in ofseti olmuş.
e- Taban İndeksli adresleme ( Based Indexed Addressing )
Bu adresleme modu da kaydedici dolaylı adreslemeye çok benzer. Kullanım formatı aşağıdaki gibidir;
mov al, [bx][si]
mov al, [bx][di]
mov al, [bp][si]
mov al, [bp][di]
BX’in 0500h SI’nın 0360h olduğunu varsayalım,
mov al,[bx][si]
gibi bir komut işlenince AL’ye kopyalanacak veri DS:0860 adresinden alınır.
Aynı şekilde;
BP=1598h DI=1004 ve mov ax,[bp+di] gibi bir komut işleniyorsa; AX, SS:259Ch ve SS:259Dh adreslerindeki veri ile yüklenir.
SI ve DI kaydedicileri için Intel’in özel komutları vardır, bu yüzden bu kaydediciler genellikle programlamada indeks değerlerini tutar, arttırır veya azaltırlar.
f- Taban İndeksli artı direkt adresleme (Based Indexed Plus Displacement Addressing)
Bu adresleme modu taban indeksli adreslemeye 8 yada 16 bitlik sabit bir değerin eklenmiş halidir.
mov al, disp[bx][si]
mov al, disp[bx+di]
mov al, [bp+si+disp]
mov al, [bp][di][disp]
BP = 1000h, BX= 2000h, SI= 0120h, DI = 5 olduğunu varsayalım.
mov al,10h[bx+si] ; AL’ye DS:2130 adresindeki veri yüklenir
mov ch,125h[bp+di] ; CH’a SS:112A adresindeki veri yüklenir
mov bx,cs:2[bx][di] ; CS:2007 adresinden itibaten 2 byte’lık veri yüklenir
TASM ve MASM ‘ın adresleme modları için esnekliği.
TASM ve MASM assembler’ları indeksli, taban indeksli, ve taban indeksli artı direkt adresleme için değişik yazım şekillerini desteklerler;
İndeksli adresleme için;
disp[bx] = [bx][disp] = [bx+disp] = [disp][bx] = [disp+bx]
Taban indeksli adresleme için;
[bx][si] = [bx+si] = [si][bx] = [si+bx] ;
Taban İndeksli artı direkt adresleme için;
disp[bx][si] = disp[bx+si] = [disp+bx+si] = [disp+bx][si] = disp[si][bx] = [disp+si][bx] = [disp+si+bx] = [si+disp+bx] = [bx+disp+si]
Yukarıda yazılan bu 3 adresleme modundaki operandlar aynı işi yaparlar. MASM ve TASM "[ ]" sembollerine "+" operatörü gibi davranır. ( disp[bx][si] = disp[bx+si] örneğinde olduğu gibi )
8086 Adresleme Hafıza Adresleme Modlarını Hatırlamak İçin Kolay Bir Yol:
8086 işlemcisi için toplam 17 adet adresleme modu mevcuttur. Bunlar disp, [bx], [bp], [si], [di], disp[bx], disp[bp], disp[si], disp[di], [bx][si], [bx][di], [bp][si], [bp][di], disp[bx][si], disp [bx][di], disp[bp][si], and disp[bp][di] adresleme modlarıdır. Aşağıdaki şekil, bu 17 adresleme modunu ezberlemeniz yerine kolayca hatırlamanıza yardımcı olacaktır.