www.packerlx.com Packer for Linux eXecutables
Ana Sayfa
Ana Sayfa
Tux
Linux
Programlama
Programlama
Projeler
Projeler
enginkuzu blog
BLOG
Eskiler
Eskiler
Ben
Ben



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 --->

AH AL
BH BL
CH CL
DH DL
BP
SP
SI
DI


<--- 16 bit register --->

CS
DS
SS
ES
FS
GS
<--- 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