Register'lar
İşlemcimizin bize sundukları üzerinden program yazdığımız için işlemcimizi de
tanımalıyız. Komut setini yani assembly komutlarını bir sonraki derste anlatmaya
başlayacağız. Registerler işlemci çalışması sırasında değişik amaçlar için
kullanılan değişkenlerdir. Bellekteki verilere ulaşmak belirli bir zaman
gerektirir, fakat registerler işlemci çekirdeğindedir ve fazladan zaman
harcanmadan istenen işleme göre içerikleri kullanılabilmektedir. Fakat sınırlı
sayıda bulunurlar. Registerler genel amaçlı kullanılabilecekleri gibi bazıları
sadece özel görevleri üstlenmektedir. Bunlar ileride anlatılacaktır. Şimdi i386
uyumlu bir işlemcinin registerlarına bakalım.
<--- 32 bit register --->
EAX |
EBX |
ECX |
EDX |
EBP |
ESP |
ESI |
EDI |
|
<--- 16 bit register --->
|
<--- 16 bit register --->
|
<--- 32 bit register --->
EIP |
EFLAGS |
|
Evet yukarıda işlemci registerlerinin çoğu görülmekte. İlk iki tablo aslında
iç içe girmektedir, fakat bu şekilde daha iyi anlışılacağını düşündüm. Aşağıda
ise bu registerlerin sınıflandırılmış halini görebilirsiniz.
Data Registers |
Pointer Registers |
Index Registers |
Segment Registers |
EAX,EBX,ECX,EDX,AX,BX,CX,DX,AH,AL,BH,BL,CH,CL,DH,DL |
EBP,ESP,BP,SP |
ESI,EDI,SI,DI |
CS,DS,SS,ES,FS,GS |
Daha önce söylediğim gibi yukarıdaki 32 bitlik işlemcimiz 8086 tabanlı olduğu
için geriye uyumlu olarak 8086 nın programlarını da çalıştırabilmelidir. Fakat
8086 işlemcisi 8 bitlik bir işlemcidir. Bu nedenle gerçekte EAX şeklindeki bir
register 32 bittir, fakat bu registerin ilk 16 bitlik bölümü AX şeklinde ifade
edilir. Bu AX şeklindeki 16 bitlik bölüm ise kendi içinde ilk 8 bitlik bölüm AL,
sonraki 8 bitlik bölüm AH olmak üzere yine alt bölümleri bulunur. Yani ben 4
byte bilgi depolamak istersem EAX,EBX gibi 32 bitlik; 2 byte bilgi depolamak
istersem AX,BX gibi 16 bit; eger 1 byte bilgi depolamak istersem AH,AL,BH,BL
registerlerini kullanabilirim. Sadece şunu unutmayın, AX,AH,AL registerleri
sadece EAX registerinin alt bölümleridir. Başka yerde depolanmazlar. Gerekli
olduğunda alt registerlere ulaşılabilir fakat gerçekte esas olan EAX dir.
Pointer ve index registerlerinde de alt bölümler bulunur. Sınıflandırma
tablosunu inceleyiniz. Kafa karıştırma olasılığına karşılık aşağıda registerleri
boyutlarına göre de sınıflandırdım.
32bit registers (4 byte) |
16bit registers
(2 byte) |
8bit registers
(1 byte) |
EAX,EBX,ECX,EDX,EBP,ESP,ESI,EDI, EIP,EFLAGS |
AX,BX,CX,DX,BP,SP,SI,DI, CS,DS,SS,ES,FS,GS,IP,FLAGS |
AH,AL,BH,BL,CH,CL,DH,DL |
Şimdi yukarıdaki registerler ne işe yarar onları
öğrenelim ? (Örnekleri bir sonraki Ders içeriğinde yer
alacak.)
AX : Akümülatör Registeri, Dörtişlem operasyonlarında kullanılmaktadır.
BX
: Base Registeri, Bellek lokasyonlarında baz adres göstericisi olarak
kullanılır, yani bir tür index registeri gibi kullanılabilir.
CX : Counter
Registeri, Döngü işlemlerinde sayaç olarak kullanılır, yani döngü kaç defa daha
dönecek bunun sayısını tutar. DX : Data Registeri, Donanım ile yapılan giriş
çıkış işlemlerinde kullanılır.
CS : Code Segment Registeri,
Segmentler bellekte bir alt bölümü işaret ederler. Önemli olan içeriklerinin ne
olduğudur. Bizim en önemli segmentimiz kod segmentdir. İçeriğinde ise tahmin
edebileceğiniz gibi yazdığımız programın komutları yer alır. Hem programcı hemde
kullanılan işletim sistemi kod segmentteki komutlar üzerine başka dataların
yazılmayacağının garantisini almalıdır. Aksi taktirde programımız garip hatalar
verir ve kitlenir. Programların sağlıklı çalışmaları için Code Segment içeriği
en önemli noktadır. (NT çekirdeği taşıyan Windows 2000 ve XP işletim sistemleri
gelişmiş bellek yönetimleri sayesinde Windows 9x sistemlere göre daha
kararlıdırlar. Windows 9x sistemlerde programlardaki hatalar sistemi
çökertebilecek seviyeye çıkabilir. Mavi ekran hataları bu sebepledir. )
DS : Data
Segment Registeri, programımızı yazarken kullandığımız değişkenler,karakter
dizileri ayrıca çalışma anında oluşturulan değişken tiplerinin tamamı bu segment
altında tutulur. SS : Stack Segment Registeri,
Stack çok özel bir data segment tipidir. Alt programlardan, dll dosyaları içinde
bulunan fonksiyonlardan, windows api fonksiyonlarından kodlar yürütülmeden önce
gerekli değişkenler bu segmente sadece bu amaçla kullanılan bir assembly komutu
ile alınırlar. Daha sonra çağırma işlemi yapılır. Önemli olan çalışma prensibini
anlamaktır. Burada diğer data segmentlerden olduğu gibi istenilen adresinden
veri çekilebilmektedir. Farkı ise stack'a yollanan son verinin çağırılma
esnasında ilk olarak geri dönmesidir. Yani son giren-ilk çıkar mantığı. (ileride
daha ayrıntılı anlatılacak) Veriler stackin sonundan başına doğru alınırlar.
Stacka son yollanan veriyi SP isimli Stack Pointeri
işaret eder.
ES : Extra Data Segment Registeri,Data segment ile
aynı özelliklere sahiptir. Özel olarak bu segmenti kullanan birkaç komut
bulunmaktadır.
FS,GS : Bu segment registerleri ihtiyaç olduğu
zaman kullanılmaktadır. Aslında ek olarak kullanılan Data Segment Registerleridir.
BP : Base Pointer, Stack segmentin başlangıç
noktasını gösterir. Yani genelde içeriği sıfırdır. SP :
Stack Pointer, Stack segment içine gönderilmiş olan son değerin (byte) adresini
göstermektedir. Stack içine veriler yollandıkça değeri azalır çünkü veri
segmetin sonundan başına doğru alınırlar. Veriler stackdan çekildikçe değeri
artar, böylece eski verileri gösterir, eski veriler silinmez ama
SP değeri değiştiği için işlem hata vermeden
yürümektedir. ***BP ve SP
aslında SI ve DI gibi
segmentler içindeki verinin adresini gösterirler. Stack Segmentin özel bir
çalışma şekli olduğu için bu Pointer registerleri özel olarak sadece Stack
Segmentin sağlıklı çalışması için görev yapmaktadır.
SI : Source Index, Data segment veya istenirse
başına küçük bir tanımlama eklenerek diğer data segmentlerdeki verileri de
göstermek için kullanılan bir index (işaretçi) registerdir. DI :
Destination Index, SI ile tamamen aynı özelliklere
sahiptir. Fakat SI ve DI
bazı string komutları tarafından kaynak ve hedef işaretçisi olarak da
kullanılmaktadır.
IP : Bir işaretçi
registerdir. Çok özel bir işaretçidir. Code Segment
içinde işlenecek bir sonraki komutun yerini işaret eder. Yaptığınız işten emin
olmadan üzerinde oynama yapmayın! FLAGS : 32
bitlik yine çok özel bir işlevi olan registerdir. Bu registerin içeriğindeki
bitler çok önemlidir. Bazı bitler anlamsızdır, diğerleri ise daha önce işlenen
komutların sonuçları ile ilgili bilgiler verir. Örneğin
CMP komutu ile iki sayı karşılaştırılır ise sayıların eşit olma veya
birinin diğerine göre büyük olması bu register içindeki bazı bitleri 1 (set)
veya 0 (reset) durumuna getirecektir. Daha sonra kullanılacak bir dallanma
komutu ile bu flaglar kontrol edilerek sonuca göre belirli adreslere dallanmalar
yapılır. İçeriğini biz direkt olarak kullanmayacağız. Bazı komutlar işleyişleri
sırasında bu registeri gizli olarak kullanmaktadırlar.
Aşağıda hangi
segmentlerin hangi işaretçi registerler ile kullanılacakları verilmektedir:
CS:IP DS:SI DS:DI SS:BP SS:SP
|