9 Ağustos 2010 Pazartesi

Assembly Bölüm 2

Bölüm 2 : Mikro İşlemci (CPU) ve Bellek
2.1 Mikro İşlemci ve Yapısı
Bugün kullandığımız bilgisayarlarda bilgileri yorumlayan ve işleyen kısım bilgisayarın
merkezi işlem ünitesidir. Merkezi işlem ünitesi (Central Processing Unit – CPU) bellek ve
çeşitli giriş/çıkış üniteleri ile bus adı verilen veri yollarını kullanarak haberleşmektedir.
İşlemciler, dahili ve dışsal hatlarının bilgi transferi ve işleyebilecekleri maksimum bilgi
kapasitesine göre 8 bitlik, 16 bitlik ve 32 bitlik işlemciler olarak adlandırılır. Bu dokümanda
anlatılan assembly dili 16 bitlik bir işlemci olan Intel 8086 (dışsal ve dahili veri transferi
word’ler halinde yapılmaktadır) serisi içindir. Dilin 8086 serisi için olması, yazdığınız
programların 8088, 80186, 80286, 80386, 80486, Pentium ve Celeron serileri ve AMD
işlemciler üzerinde çalışmayacağı anlamına gelmemektedir.
İşlemci, register adı verilen bölmelerden oluşur. Bu register’ları Data register’ları, Pointer
ve Index register’ları, Segment register’ları, Instruction Pointer (komut göstergeci) ve
Program Status Word (Flag register’ı) olarak gruplandırabiliriz. Aşağıda 8086 işlemcinin
register yapısı basitçe gösterilmiştir.
2.1.1 Data Register’ları
Şekilde de görüldüğü gibi 8086 işlemci 14 adet 16-bit kapasiteli register’a sahiptir. Bu
register’lardan Data register’ları ( AX, BX, CX ve DX ) kendi içlerinde 8-bit kapasiteli iki
register’a bölünmektedir. Bu register’lar AX için AH ve AL, BX için BH ve BL, CX için CH
ve CL ve DX için DH ve DL olarak adlandırılır. AH, 16-bitlik AX register’ının 8-bitlik
yüksek(High) seviyeli bölümü ve AL ise 16-bitlik AX register’ının 8-bitlik alçak (Low)
seviyeli bölümü olarak adlandırılır. Programlarımızı yazarken 8-bitlik verilerin işlenmesinde
bu 8-bitlik register’lardan faydalanırız. Daha sonraki bölümlerde de göreceğimiz gibi data
register’ları bir çok işlemde (döngülerde, interrupt kullanılmasında, matematiksel
işlemlerde...) CPU tarafından rezerv edilmişlerdir. Bu durumlarda bizim register içerisindeki
değeri değiştirme şansımız yoktur.
12
Programlarımızda BH veya BL register’ının değerinin değişmesi doğrudan BX register’ının
değerini değiştirecektir. Aynı durum diğer data register’ları için de geçerlidir. Bir örnek
vermek gerekirse: BX register’ımızın değeri A43F olsun. Bu durumda BH=A4 ve BL=3F
olur. Simdi BL’nin değerini 05 olarak değiştirelim. Son durumda BX=A405, BH=A4 ve
BL=05 olacaktır. (Yukarıdaki şekil incelenirse verilen örnek daha kolay anlaşılacaktır)
2.1.2 Pointer ve Index Register’ları
Pointer ve index register’ları bellek içerisindeki herhangi bir noktaya erişmek için kullanılır.
Bu iş için erişilmek istenen noktanın offset ve segment adresleri gerekli register’lara atanarak
işlem gerçekleştirilir. ( Bölüm 2.2, Bellek ve Yapısı kısmında bu konu daha ayrıntılı ele
alınacaktır.)
2.1.3 Segment Register’ları
Segment register’ları (CS, DS, SS ve ES) , programımız bilgisayarın belleğine yüklendiği
zaman bellek içerisinde oluşturulan bölümlerin (Segment) başlangıç adreslerini tutarlar. Yani
bu register’lara bir çeşit yer göstergeci denebilir. CS, programımızın çalıştırılabilir kodlarını
barındıran (Code Segment) bellek bölgesinin başlangıç adresini tutar. Yani CS ile gösterilen
yerde makine dili kodlarımız vardır. DS, programımız içerisindeki değişkenlerin saklandığı
bölümdür. SS, bellekte programımız için ayrılan stack bölümünün başlangıç adresini tutar.
Stack, ileride göreceğimiz PUSH ve POP komutları ile belleğe değer atılması ve alınması
için, programların ve fonksiyonların sonlandırıldıktan sonra nereye gideceklerini belirten
adres bilgisini tutmak için ve program ve fonksiyonlara gönderilen parametreleri saklamak
için kullanılır. UNIX tabanlı sistemlerde kesme (interrupt) kullanımı için gerekli
parametrelerin belirtilmesi için de stack kullanılır. ES (Extra segment) daha çok dizgi
işlemleri için kullanılır.
2.1.4 Instruction Pointer
Instruction Pointer register’ı işlemci tarafından işlenecek bir sonraki komutun bellekteki
adresini saklar. Bu register üzerinde programcı tarafından herhangi bir işlem yapılamaz. Her
komut işletildikten sonra CPU otomatik kullanılan komuta göre gerekli değeri bu register’a
atar.
2.1.5 Flag Register
Flag Register diğer register’lardan daha farklı bir durumdadır. Diğer resigterların 16-bit
halinde bir bütün olarak ele alınmalarından farklı olarak flag register’ın her biti CPU için ayrı
bir değere sahiptir (8086 işlemci tarafından sadece 9 tanesi kullanılmaktadır). Bu bitlerin özel
olarak isimlendirilmeleri aşağıda verilmiştir.
O : Overflow flag
D : Direction flag
I : Interrupt flag
T : Trace flag
S : Sign flag
Z : Zero flag
A : Auxilary Carry flag
P : Parity flag
C : Carry flag
13
Bilgisayar ikilik sayı sistemini kullandığına göre bu register’lar içerisindeki değer herhangi
bir anda ya 1 yada 0’dır. Bir bitin 1 olma durumuna “Set”, 0 olma durumuna ise “Reset”
denir. İşlemci birçok komutu icra ederken bu bitlerin durumlarından faydalanır.
2.1.5.1 Carry Biti
İşlemci tarafından yapılan herhangi bir işlem sırasında alıcı alana yerleştirilen sayının alıcı
alana sığmamasından doğan olaya “carry”(taşma) denir. CPU bir işlem sonucunda taşma ile
karşılaşırsa carry flagın değeri 1 yapılar.
Aşağıda 16-bitlik iki sayı toplanmıştır ve sonuçta bir taşma olmuştur. (Taşan bit kırmızı ile
gösterilmiştir)
1111 1001 0110 1010 􀃆 F96A
0010 1010 1111 1001 􀃆 2AF9
+----------------------------
1 0010 0100 0110 0011 􀃆 2463 CF=1
F96A ile 2AF9’un toplanması sonucu 2463 sayısı elde edilmiştir ki bu iki sayıdan da küçüktür.
Elimizdeki sayılar pozitif olduğuna göre toplama işlemi sonucunda elimizdeki sayılardan daha
küçük bir sayı elde etmemiz imkansızdır. CPU bu durumda carry flagın değerini 1 yaparak 17-
bitlik bir sayı elde eder.
C:\WINDOWS\Desktop>debug
-a100
1E40:0100 MOV AX,F96A
1E40:0103 MOV BX,2AF9
1E40:0106 ADD AX,BX
1E40:0108
-t
AX=F96A BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=1E40 ES=1E40 SS=1E40 CS=1E40 IP=0103 NV UP EI PL NZ NA PO NC
1E40:0103 BBF92A MOV BX,2AF9
-t
AX=F96A BX=2AF9 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=1E40 ES=1E40 SS=1E40 CS=1E40 IP=0106 NV UP EI PL NZ NA PO NC
1E40:0106 01D8 ADD AX,BX
-t
AX=2463 BX=2AF9 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=1E40 ES=1E40 SS=1E40 CS=1E40 IP=0108 NV UP EI PL NZ AC PE CY
1E40:0108 A394D3 MOV [D394],AX DS:D394=A2A2
Yukarıdaki ekran görüntüsü verdiğim örneğin debug programı altında denenmesi sonucu elde
edilmiştir.
İlk önce “MOV AX,F96A” ile AX register’ının değeri F96A yapılmıştır. Bunu ilk t
komutundan sonra AX=F96A ile görebiliriz (1. t komutundan sonraki bölümde AX’in değerini
inceleyin). Daha sonra “MOV BX,2AF9” ile BX’in değeri 2AF9 yapılmıştır (2. t komutundan
sonraki bölümde BX’in değerini inceleyin). En son “ADD AX,BX” ile bu iki değer toplanıp
AX’e atanmıştır. Son “t” komutundan sonra AX=2463 olmuştur ve en sondaki “NC” ifadesi
“CY”ye dönüşmüştür ki bu da işlemin sonucunda bir taşma olduğunu gösterir.
14
2.1.5.2 Parity Biti
Bir işlem sonucunda word’un düşük seviyeli baytı iki ile tam bölünüyorsa bu bite 1 aksi
taktirde 0 atanır. İşlemin yüksek seviyeli baytındaki sayının iki ile bölünüp bölünmemesi bu
flag için önemli değildir.
2.1.5.3 Auxilary Carry Biti
CPU tarafından gerçekleştirilen işlem sonucunda alıcı alanın ilk dört biti üzerinde bir taşma
gerçekleşiyorsa bu flagın değeri 1 yapılır.
Yukarıda carry flag için verilen örnekte ilk sayının ilk dört biti olan 1010 (hex A) ve ikinci
sayının ilk dört biti olan 1001 (hex 9) toplamı sonucu 0011 sayısı elde edilmiş ve bir sonraki
bite bir elde sayı aktarılmıştır. ADD işlemi öncesinde NA (0) olan bitin değeri, işlem
sonrasında AC (1) olmuştur.
2.1.5.4 Zero Biti
Yapılan herhangi bir işlem sonucu sıfır ise bu flag set edilir.
-a100
1E40:0100 mov ax,12
1E40:0103 xor ax,ax
1E40:0105
-t
AX=0012 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=1E40 ES=1E40 SS=1E40 CS=1E40 IP=0103 NV UP EI PL NZ NA PO NC
1E40:0103 31C0 XOR AX,AX
-t
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=1E40 ES=1E40 SS=1E40 CS=1E40 IP=0105 NV UP EI PL ZR NA PE NC
1E40:0105 F0 LOCK
1E40:0106 01D8 ADD AX,BX
Yukarıda önce AX register’ının değeri 12 yapılıyor. Daha sonra bu register kendisi ile XOR
işlemine tabi tutulmuştur. Bir sayının kendisi ile XOR işlemine tabi tutulması sonucu 0 elde
edilir. Bu durum zero flagın değerini set etmiştir ( NZ 􀃆 ZR ).
2.1.5.5 Sign Biti
İşaretli sayılarda bayt (8 bit) için sayının 7. ve word (16 bit) için sayının 15. biti işaret biti
olarak adlandırılır. Yapılan bir işlem sonucunda alıcı alan içersindeki işaret biti sign flag
içerisine kopyalanır. Yani sign bitinin değeri 0 ise elde edilen sonuç pozitif, 1 ise elde edilen
sonuç negatif kabul edilir.
2.1.5.6 Trace Biti
CPU’nun sadece bir komut çalıştırıp beklemesi için kullanılır. DEBUG’ın kullandığı “Trace”
işlemi bu flagın set edilmesi ile gerçekleştirilir.
2.1.5.7 Interrupt Biti
CPU’nun çeşitli aygıtlardan gelen kesme isteklerini dikkate alıp almayacağını bildirir. 0 olması
durumunda istekler dikkate alınmayacaktır.
15
2.1.5.8 Direction Biti
Bu flagın değeri genellikle dizgi işlemleri üzerindeki işlemin yönünü belirtmek için kullanılır.
2.1.5.9 Overflow Biti
İşaretli sayılar üzerindeki taşmayı kontrol etmek için kullanılır. Hatırlarsanız işaretsiz sayılar
için carry flagı kullanılmıştır. Fakat durum işaretli sayılar için biraz daha farklıdır. İşaretli
sayılarda meydana gelecek bir taşma bayt veya wordun işaret bitini etkileyeceği için pozitif
(işaret biti 0) olan bir işaretli sayının taşma sonucu negatif (işaret biti 1) gibi algılanması
mümkündür. Bu durumda overflow flagı set edilir ve işlem sonucunun yanlış algılanması
engellenir.
2.2 Bellek ve Yapısı
Bilgisayarımızda bir program çalıştırdığımız zaman program önce RAM’e yüklenir ve daha
sonra çalıştırılır. Yükleme işlemi programın kod, data gibi bölümlerinin çeşitli belek alanlarına
ayrı ayrı yüklenmesi ile yapılır. Bu alanlara segment adı verilir. 8086 işlemcide bu
segmentlerden her birinin boyu 64 Kb (65535 bayt) boyundadır. Bu değer 32-bit işlemcilerde 4
Gb kadardır. Biz 8086 işlemci ve 16-bit uzunluğundaki bellek bölgeleri ile çalıştığımıza göre
adresleyebileceğimiz maksimum alan 64 Kb boyundadır. 8086 işlemci programcıya üzerinde
çalışabileceği dört adet segment sağlar. Bunlar : CODE, DATA, EXTRA ve STACK
segmentleridir. Bu segmentlerin başlangıç adresleri CODE SEGMENT için CS’de, DATA
SEGMENT için DS’de, EXTRA SEGMENT için ES’de ve STACK SEGMENT için SS’de
saklanır.
Yukarıda anlattığımız 64 Kb’lık segmentler de kendi içlerinde 1 baytlık bölümlere
ayrılmışlardır. Segmentlerin içerisindeki bu bir baytlık bölümlere OFFSET adı verilir. Yani bir
segment içerisinde 65535 tane offset vardır. Programcı tarafından girilen her komut tuttuğu
bayt sayısı kadar offset adresini ileri alır.
Bellek içerisindeki herhangi bir noktaya erişmek için SEGMET:OFFSET ikilisi kullanılır.
Code segment içerisindeki bir noktaya erişmek için segmet adresi olarak CS’deki değer ve
offset adresi olarak IP içerisindeki değer kullanılır. Aynı şekilde stack segment içerisindeki bir
değere ulaşmak için segment adresi olarak SS içerisindeki değer ve offset adresi olarak SP veya
BP’den biri kullanılır.
Bellek ve verilerin nasıl depolandığı konusunda aşağıdaki örnek size yardımcı olacaktır.
-A100
1E40:0100 MOV AH,01
1E40:0102 INT 21
1E40:0104 CMP AL,45
1E40:0106 JNE 0100
1E40:0108 INT 20
1E40:010A
-G
GGHJRE
Program normal olarak sonlandırıldı
-U 100
1E40:0100 B401 MOV AH,01
1E40:0102 CD21 INT 21
1E40:0104 3C45 CMP AL,45
1E40:0106 75F8 JNZ 0100
1E40:0108 CD20 INT 20
1E40:010A D3E8 SHR AX,CL
1E40:010C 94 XCHG SP,AX
1E40:010D 00726D ADD [BP+SI+6D],DH
16
1E40:0110 E87000 CALL 0183
1E40:0113 A396D3 MOV [D396],AX
1E40:0116 8A04 MOV AL,[SI]
1E40:0118 3C20 CMP AL,20
1E40:011A 740C JZ 0128
1E40:011C 3400 XOR AL,00
1E40:011E 2F DAS
1E40:011F 1E PUSH DS
-
Yukarıdaki kısa program klavyeden girilen her tuşu okur ve girilen ‘E’ oluncaya kadar okuma
işlemine devam eder. (Bu arada programın boyunun sadece 10 bayt olduğuna dikkat edin. C
veya Pascal ile aynı program kaç KB tutardı acaba!! ☺ ). Önce programı yazdık ve daha sonra
“G” ile çalıştırdık. En son olarak da “U 100” ile 100. offset adresinden itibaren dağıtma
(unassemble) işlemi yaptık. Dikkat ederseniz her satırın başında “1E40:0104” gibi, iki nokta
ile ayrılmış iki sayı var. Bu sayılar sırası ile komutun segment ve offset adresleridir. Yani
bilgisayarımızın 1E40. segmenti o anki geçerli kod segmentimiz ve bu segment içerisindeki
0104. offset de (aslında 0104. ve 0105. offsetler) içerisinde “CMP AL,45” komutunu
barındırmaktadır. Bir sonraki satırda bu sayılar “1E40:0106” halini alıyor ki buda bize offset
adresimizin 2 arttığını gösteriyor. Yani “CMP AL,45” komutu bilgisayarımızın belleğinde 2
baytlık yer kaplıyor. Dağıtma işleminde segment ve offset adreslerinin sağındaki sayılar ise
sizin girdiğiniz komutların bellekte bulundukları hallerinin on altılık tabandaki karşılıklarıdır.
İşte bilgisayar asıl olarak bilgiyi belleğinde sayılar halinde saklar ve assembly dili bu sayıların
insan için daha okunur hale gelmiş halidir. Yani CPU “3C45” (0011 1100 0100 0101 = 16-bit )
ile karşılaştığı zaman bunun bir karşılaştırma komut olduğunu anlar ve ona göre işlem yapar.
Diğer komutlarda aynı şekilde işlem görmektedir. Eldeki bilginin komut mu yoksa bir değişken
mi olduğu, bilginin bulunduğu segment aracılığı ile anlaşılır.
2.3 Stack
Yüksek seviyeli programlama dillerinde değerler değişken adı verilen alanlarda saklanır.
Assembly dilinde ise programcı değerleri saklamak için CPU register’larını ve stack’ı
kullanılır. Stack, bilgilerin geçici olarak depolandığı bir bölümdür. 8086 işlemci programcıya
64 Kb boyundu bir stack segment sağlar. Bu segmentin başlangıç adresi SS içerisinde ve o anki
geçerli offset adresi ise SP (Stack Pointer) içerisinde bulunur.
Stack içerisinde, program içerisindeki fonksiyonların geri dönüş değerleri, fonksiyonlara
aktarılan argümanlar, komut satırı parametreleri gibi değerler saklanır. Ayrıca programcı bazı
değerleri geçici olarak bu alana depolayıp daha sonra kullanabilir.
Stack içersinde yerleştirme işlemi kelimeler (word) halinde olur. Yani, stack üzerinde bir
işlemde her seferinde iki offset geriye veya ileriye gidilir. Stack programcıya sıralı erişim
sağlar. Stack segmentimizin 0000-FFFF arasında değişen offset adresleri ve SP’nin o anki
değerinin FFFF olduğunu varsayarsak, stack üzerine konulacak ilk değer FFFF ve FFFE
adreslerine yazılır (İki bayt veri yazılıp okunabilir). Daha sonra SP’nin değeri yazılacak bir
sonraki değerin adresini
belirtmek üzere FFFD olarak değiştirilir.
17
Yukarıda stack pointer’ın ilk değeri FFFF’dir (Şekil1). Stack üzerine ilk bilgi aktarımından
sonra bir sonraki bilginin yazılacağı adresi belirtmek için SP=FFFD oluyor (Şekil 2). FFFF ve
FFFE adreslerine sırasıyla 89 ve 67 sayıları yazılmış. Bu bize stack üzerine yazılan bilginin
6789h olduğunu gösteriyor. Aynı şekilde, daha sonra 1234h değeri stack üzerine aktarılıyor
(Şekil 3) ve SP’nin değeri FFFB olarak değişiyor. Şekil 4’te stack üzerinden bilgi alınıyor. İlk
iki işlemin tersine bu sefer SP’nin değeri 2 artıyor ve FFFB+2=FFFD oluyor. Yani o andan
sonra yazılacak ilk değer FFFD ve FFFC adreslerine yazılacaktır. Kısaca, stack üzerine bilgi
yazıldığı zaman SP’nin değeri azalır ve bilgi okunduğu zaman artar.
Stack LIFO (Last-In First-Out) prensibi ile çalışır. Yani stack üzerine yazılan en son bilgi
alınabilecek ilk bilgi ve yazılan ilk bilgi de alınabilecek son bilgidir. Yukarıdaki örnekte ilk
önce 6789h sayısı daha sonra 1234h sayısı stack üzerine yazıldı. İlk yazılan değer olan 6789h’a
ulaşmak için önce 1234h okunmalı.
Stack üzerindeki işlemler PUSH ve POP komutları ile gerçekleştirilmektedir.
MOV komutu: Bir sonraki bölüm olan “80x86 İşlemcilerde Bellek Adresleme” kısmında bellek
ve CPU register’ları arasındaki bilgi transferi MOV komutu kullanılarak anlatılacaktır.
MOV hedef,kaynak
MOV komutunun kullanım şekli yukarıdaki gibidir. Bu komut “kaynak” içerisindeki bilgiyi
“hedef”e aktarır. Yani
MOV AX, 1234h
MOV BX, AX
Yukarıda ilk önce AX register’ına 1234h değeri yazılmıştır. Daha sonra bu değer AX
register’ından BX register’ına aktarılmıştır. Yani Program sonunda AX=1234h ve BX=1234h
olur.
Komutun kullanımında dikkat edilmesi gereken en önemli nokta “hedef” ve “kaynak”
alanlarının eşit boyutlarda olmasıdır (Örneğimizde 16-bit.).
18
2.4 80x86 İşlemcilerde Bellek Adresleme
8086 işlemci programcıya belleğe ulaşım için 17 çeşit adresleme metodu sağlar. Assembly
programlama dilinde bellek adresleme ve belleğe erişim en önemli ve iyi bilinmesi gereken
konulardandır.
• Displacement-only
• Base
• Displacement + Base
• Base + Indexed
• Displacement + Base + Indexed
Kullanılan 17 çeşit adresleme metodu yukarıdaki beş ana kategoriden türetilmektedir.
2.4.1 Doğrudan Adresleme (Direct Addressing)
Bu adresleme metodu anlaşılması en kolay olandır. Bu yolla adresi verilen herhangi bir bellek
gözüne okuma veya yazma yapılır. Kullandığımız bellek 16-bit’lik adreslerden oluştuğuna göre
adres sabitlerimiz de dört hanelik on altılık sayılardan oluşmalıdır.
MOV AX, [4126]
MOV CX, CS:[4A4C]
MOV DS:[41C8], BX
Yukarıda ilk satırda “MOV AX, [4126]” ile bellekteki 4126h ve 4127h adreslerindeki
değerler AX register’ına atanmıştır. 4126h adresi 1 bayt ve AX register’ı 2 bayt olduğu için
hem 4126h hem de 4127h adresindeki değerler okunmuştur.
İkinci örnekte Code Segment içerisindeki 4A4Ch ve 4A4Dh adresindeki değerler CX
register’ına atanmıştır. Gördüğünüz gibi “CS:[4A4C]” gibi bir ifade kullanarak istediğiniz
herhangi bir segment içerisindeki bilgiye erişebiliyorsunuz.
Son olarak da “MOV DS:[41C8], BX” komutu ile BX içerisindeki değer Data Segment
içerisindeki 41C8h ve 41C9h adreslerine yazılıyor.
2.4.2 Dolaylı Adresleme (Indirect Addressing)
Bu metot ile herhangi bir register içerisinde barındırılan değerin gösterdiği bellek
bölgesindeki alan ile işlem yapılır. Bu metot için kullanılabilecek dört register BX (Base), BP
(Base Pointer), SI (Source Index) ve DI (Destionation Index)’dır. Bu yol ile adreslemeye
aşağıda birkaç örnek verdim.
Based
MOV BX, 1234
MOV AX, [BX]
Önce BX’in değeri 1234h olarak
değiştiriliyor. Daha sonra bellekte
1234 ile işaret edilen yerdeki değer
AX içerisine atanıyor. Yani
yandaki komut kümesi
MOV AX, [1234]
ile aynı işi yapıyor.
Based
MOV BP, 45C8
MOV AX, [BP]
BP = 45C8h
MOV AX, [45C8]
19
Indexed
MOV DI, 76A7
MOV AX, [DI]
DI = 76A7h
MOV AX, [76A7]
Indexed
MOV SI, D78C
MOV AX, [SI]
SI = D78Ch
MOV AX, [D78C]
İlk iki adresleme yönteminde Base register’lar olan BX ve BP kullanıldığı için bu yöntem
Based olarak adlandırılır. Aynı şekilde DI ve SI ile yapılan adreslemelerde de Index register’lar
kullanıldığı için Indexed olarak adlandırılır.
Bir önceki bölümde olduğu gibi bu yöntemde de ulaşılmak istenen offset için ayrı bir
segment belirtilebilir. Yukarıda BX, DI ve SI ön tanımlı olarak DS (Data Segment)’i kullanır.
BP için ön tanımlı segment SS ( Stack Segmenttir).
2.4.3 Indexed Adresleme
Bu metot ile istenilen yere ulaşmak için hem bir sabit hem de yukarıdaki gibi bir register
kullanılır. İstenilen offset adresi kullanılan sabit ile register içerisindeki değerin toplamıdır.
Yine yukarıda olduğu gibi BX, DI ve SI ön tanımlı olarak DS’i ve BP ön tanımlı olarak BP’yi
segment olarak kullanır. Tabi ki istenildiği taktirde farklı segmentlerdeki verilere ulaşmak
mümkündür.
MOV BX, 7A82
MOV AL, 78[BX]
BX = 7A82
7A82 + 78 = 7AFA
MOV AL, [7AFA]
Gördüğünüz gibi yukarıda “MOV AL, 78[BX]” komutu ile BX içerisinde bulunan 7A82h
değeri ile sabitimiz olan 78h değerini toplamı olan 7AFAh offseti içerisindeki değer AL’ye
atanıyor. Tabi, BX kullanıldığı için kaynak segment olarak Data Segment kullanılmaktadır.
2.4.4 Based Indexed Adresleme
Bu yöntem dolaylı adresleme yöntemi ile benzerlik göstermektedir. Tek fark burada bir değil
,biri Base diğeri Index register olmak üzere iki farklı register kullanılmasıdır. Hedef bölgeye
atanacak değer bu iki register içerisindeki değerin toplamının gösterdiği offset içerisindeki
değerdir.
MOV BX, D854
MOV SI, 278C
MOV AL, [BX][SI]
BX = 7A82
SI = 278C
D854 + 278C = FFE0
MOV AL, [FFE0]
20
MOV BP, 54AC
MOV DI, 4444
MOV AL, [BP][DI]
BP = 54AC
DI = 4444
54AC + 4444 = 98F0
MOV AL, [98F0]
Yukarıdaki ilk örnekte ön tanımlı segment Data Segment ve ikincide ise Stack Segmenttir.
2.4.5 Based Indexed + Sabit(Disp) Adresleme
Bu yöntem yukarıdaki bütün yöntemleri kapsar. Genel formu aşağıdaki gibidir ve register’lar
içerisindeki değer ile sabitin toplamının verdiği offset adresindeki değer ile işlem yapılır.
MOV AL, DISP[BX][SI]
MOV BL, DISP [BX+DI]
MOV BH, [BP+SI+DISP]
MOV AH, [BP][DI][DISP]

Hiç yorum yok:

Yorum Gönder