Assembly Programlama Dili (Bölüm -2 )

Programlama dilleri konusunda bilgi paylaşım alanıdır.
Cevapla
Kullanıcı avatarı
mayhemious
Kilobyte4
Kilobyte4
Mesajlar: 711
Kayıt: 17 Kas 2007, 13:14
cinsiyet: Erkek

Assembly Programlama Dili (Bölüm -2 )

Mesaj gönderen mayhemious » 26 Kas 2007, 21:17

REGISTERLER :



Evet arkadaslar geldik registerler (Namı diger Yazmaçlar nedense bu kelimeyi görünce sinir oluyorum ben buna kaydedici demeyi uygun buluyorum ama bilmeniz açısından yazdım ) konusuna, bu konuda oldukça kolay arkadaslar.Makaleyi okudukta sonra anlayacagınızdan eminim.Registerleri kısaca söyle tarif edebiliriz, programlamayla ilgilenen arkadaslar bilirler,hani program yazarken degisken dedigimiz ,(a=53 , b= ”atmaca” gibi)deger atama durumları vardır ya hani,iste registerleri de bu degiskenlere benzetebiliriz.Örnegin b=”atmaca” degiskenimize baska herhangi bir deger atamadıgınız sürece “b” ‘nin degeri hep “atmaca olacaktır.Taki bir deger atarsanız ,mesela 42 derseniz o zaman “b” ‘nin tasıdıgı deger 42 olur.Bunun gibi registerler de (yani kaydediciler) CPU' nun her türlü islemlerini yerine getirmesi için bu görevi yerine getirirler.

Kısaca söyle de diyebiliriz ,islemci yani CPU register adı verilen bölmelerden olusur ve bu registerler de mikroislemcinin en temel bilesenlerinden biridir .Bu registerleri ben 4 bölüme ayırmayı uygun buluyorum kimileri 3 yada 5 bölüm olarak inceleyebiliyor.



1-GENEL AMAÇLI REGİSTERLER

AX = Accumulator Register

BX = Base (Taban )Register

CX = Counter (Sayaç )Register

DX = Data (Veri )Register

2-SEGMENT REGİSTERLERİ

CS = Code Segment Register

DS = Data Segment Register

SS = Stack Segment Register

ES = Extra Segment Register

3-OFFSET REGİTERLERİ

IP = Instraction Pointer Register

SP = Stack Pointer Register

BP = Base Pointer Register

a-)İndex Registerler



SI = Source (Kaynak )Index Register

DI = Destination (Hedef)Index Register

4-FLAG (BAYRAK )REGİSTERLERİ

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





Evet registerlerimiz bunlar,siz simdilik hepsini de ezberlemeye kalkmayın zamanla programlar üzerinde durdukça ögreneceksiniz,bunlardan özellikle flag (bayrak )registerleri sadece bilgi almak açısından kullanırız ,yoksa bunlar üzerinde islem yapamayız.İslem sonunda esitlik var mı yok mu,veya islem sonunda tasma oluyor mu ya da olmuyor mu; gibi bilgileri görmek için kullanırız.Ben yine de mümkün oldugu kadar karsılarına Türkçe karsılıklarını da yazdım ki zorlanmayasınız.Bunların bir kısmını ayrıntılı olarak sonraki konularda anlatacagım zaten.



1-GENEL AMAÇLI REGİSTERLER :



Yukarıda görmüs oldugunuz (ax ,bx ,cx ve dx )registerleri eski 8 ve 16 bit islemciler ( 8086,80186 gibi) için bu sekilde kullanılıyordu.Fakat bu islemciler günümüzde pek kalmadı ve yeni 32 bit islemciler daha yaygın bir sekilde kullanılıyor.Bunun içinde bu register isimlerinin basına Extended (Genisletilmis ) kelimesinin “e” harfi getirildi.Yani EAX-EBX-ECX-EDX seklinde oldular.Bizde bundan sonra bu Genel Registerler ,Segment Registerler ,Ofset ve İndex registerleri yazarken bu sekildeyazacagız.EBX-EDI-ESI-ESP vs gibi..

Bir ornek ;



Mov eax,24

Mov ebx, 10

Add eax , ebx

Sonuç = 34



Dönelim bu genel kaydedicilere ,bunlar kendi aralarında 2’ye bölünerek 8 adet olurlar.söyle ki;

EAX = AH - AL

(32 BİT)= (16 BİT) - (16 BİT)

EBX = BH - BL

(32 BİT)= (16 BİT) - (16 BİT)

ECX = CH - CL

(32 BİT)= (16 BİT) - (16 BİT)

EDX = DH - DL

Eger bunlar 16 bit lik registerler olsaydı o zaman da 8 bit AH , 8 bit AL olarak degisecekti.Sonlarına eklenen H ve L harfleri “H” High (Yüksek)- “L” ise Low (Düsük) kelimelerinden gelmistir. 16 bitlik bir register en fazla 65535 degerini alırken 32 bitlik bir register 4294836225 degerine kadar alır.

EAX register programlarda en çok kullanılan yazmaçlardan biridir. Accumulator’ün kısaltılması sonunda olusan EAX yazmacı bütün giris ve çıkıs islemlerinde ve bazı aritmetik islemlerde kullanılır.

EBX Registeri Base register olarak da bilinir. RAM islemlerinde adreslemede kullanılır. Register adresleme islemlerinde daha çok offset degerlerini tutar. Ayrıca hesaplama islemlerinde de kullanılır.

ECX Registeri Counter registeridir. Döngü islemlerinde ve kaydırma islemlerinde sayaç olarak kullanılırIZ.

EDX Register bazı giris çıkıs islemlerinde ve matematiksel islemlerde kullanılır.Daha çok çarpma ve bölme islemlerinde büyük sayıları saklamak için AX registerinin bir parçasıymıs gibi kullanılır.



2-SEGMENT REGİSTERLERİ :



Segment register’ ları (ECS, EDS, ESS ve ES) programımız bilgisayarın bellegine yüklendigi

zaman bellek içerisinde olusturulan bölümlerin (Segment) baslangıç adreslerini tutarlar. Yani bu register’lar için bir çesit yer göstergeci diyebiliriz. ECS, programımızın çalıstırılabilir kodlarını barındıran (Code Segment) bölgesinin baslangıç adresini tutar. Yani ECS ile gösterilen yerde makine dili kodlarımız vardır. EDS ise, programımız içerisindeki degiskenlerin saklı tutuldugu bölümdür. ESS (Stack), bellekte programımız için ayrılan stack bölümünün ( ki bu bölümü ayrı bir sekilde asagıda anlatacagım ) baslangıç adresini tutar.ES (Extra segment) ise daha çok dizi yani string (Numerik olmayan) islemleri için kullanılırız.



3-OFFSET VE İNDEX REGİTERLERİ :



Offset ve index register’ları bellek içerisindeki herhangi bir noktaya erisim saglamak için kullanılır.Bu islem için erismek istedigimiz bölgenin offset ve segment adresleri gerekli register’lara aktarılır bizde bu sekilde islemi gerçeklestirmis oluruz..

Instruction Pointer register’ı ise CPU tarafından islenecek olan bir sonraki komutun bellekteki adresini tutar. Bu register üzerinde programcının hiçbir eylemi olamaz. Her komut icra edildikten sonra CPU otomatik olarak kullanılan komuta göre gerekli degeri bu register’a atar.Arkadaslar belki biraz agır bir anlatım gibi görünebilir fakat bunların baska bir izah seklini bulamadım yani su an aklıma gelmiyor.

4-FLAG (BAYRAK )REGİSTERLERİ :



Arkadaslar bunları detaylı bir sekilde anlatmadan önce sunu hatırlatmak istiyorum.Bayrak kaydedicisindeki her bir bitin 1 olma durumuna SET, 0 olma durumuna da RESET denir. İslemcinin ürettigi bu sonuçlar hakkında programcı bunlara bakarak islem durumunu analiz eder.

Overflow flag (OF): Biz buna tasma biti de diyebiliriz. İsaretli (negatif)sayı üzerinde meydana gelen tasma durumunu tespit etmek amacıyla kullanılır. Yani islem sonucunda isaret biti degismisse bu flag set edilir,yani 1 degerini alır.

Direction flag(DF): Bizim kullanmadıgımız bir bayraktır.String islemlerini yapan komutlar için kullanılır.Yani bir stringi hafızanın bir yerinden diger bir yerine kopyalarken CPU tarafından kullanılmaktadır. İslemci bu bayraga bakarak transferin yönünü belirler.

Interrupt flag (IF) : Buna kesme bayragı da diyebiliriz. CPU’nun çesitli aygıtlardan gelen kesme isteklerini dikkate alıp almayacagını bildirir. 0 olması durumunda istekler dikkate alınmaz,1 olursa alır.

Trace flag (TF) : Trace biti de diyebilecegimiz bu bayrak CPU nun sadece 1 komut çalıstırma yapması için kullanılır.Hani Debugger ile bir programı açıp programda adım adım ilerliyoruz ya ,iste CPU bunu ,bu bayragın durumuna göre yapar 1 olursa isletilmeye hazırdır demektir..

Sign flag (SF) : Yapılan islem sonucunda elde edilen sayının en solundaki bit 1 ise bu negatif bir sayıdır demektir ve bu bayrakta 1 degerini döndürür.Eger ki 0 ise pozitiftir ve bayrak 0 degerini yansıtır.Kısaca bu bayrak sayının negatif veya pozitif oldugunu gösterir.

ADD EAX, EBX

Eger SF nin degeri 1 ise o zaman EAX deki sayı negatif bir sayı deriz.

Zero flag (ZF) : Bir islemin toplam sonucu 0 ise bu flag set edilir yani 1, degilse reset yani 0 edilir.Bu bayragı karıstırmayın arkadaslar tekrar ediyorum eger islem sonunda sonuç 0 ise ,bu bayrak 1 degerini döndürüyor.Mesela

SUB EAX, EBX

isleminde iki register’ın degerleri esitse sonuç 0 olacagı için ZF set (1)edilecektir.Asagıdaki Olly debugger ile aldıgım örnek resim olayı kavramanıza yardımcı olacak.






Yukarıdaki resimde JE (jump if equal)komutunu görüyorsunuz burada bir üstündeki OR komutuyla (Daha sonra detaylı sekilde anlatacagım)islem sonu kontrol ediliyor ve esitlik var ise JE ile gösterilen adrese atla deniyor.Ancak asagıdaki resimde gösterdigim gibi Z bayragı 0 (sıfır)gösterdigi için atlama gerçeklesmeyecektir.


Auxilary Carry flag (AF) : Dördüncü bit’ten besinci bit’e dogru olusan elde durumunda set edilir. Elde yoksa reset edilir. Özellikle BCD (binary coded decimal) islemleri için düsünülmüstür.Zaten sizin sık kullanacagınız bir sey degil o nedenle fazla üstünde durmuyorum.

Parity flag (PF) : 16 bitlik bir islem sonrasında düsük anlamlı byte içerisindeki 1’lerin sayısı çift ise bu bit set edilir 1 olur , tek ise reset edilir o olur. Yani düsük seviyeli bayt bölümündeki 1’lerin sayısı iki ile tam bölünüyorsa bu bayraga 1 aksi taktirde 0 atanır.

Carry flag (CF) : Bu bayrak da Overflow bayragına benzer ,ancak aralarında ki önemli fark su arkadaslar.Overflow bayragı isaretli yani negatif sayılar için kullanılır demistik.Carry (elde)bayragı da isaretsiz pozitif sayılar için kullanılır.Yine aynı isi yapar yani bir islem sonunda CPU tasma ile karsılasırsa carry flag’ın degerini 1 yapar set eder.





ADRESLEMELER :



Bildiginiz gibi programları olusturan kodlar ve veriler hafızaya yüklendikten sonra islemci tarafından satır-satır icra edilirler. Ayrıca CPU tüm giris-çıkıs islemlerini de hafızaya eriserek yapar. Bazen hafızadan dogrudan bir kod ya da veri alır, isler. Bazen hafızaya bir veri gönderdiginizde birde bakmıssınız bu bir yazıcıdan belge olarak çıkmıs . İste bilgisayarın donanım ve yazılım olayın da yaptıgı bunca çesitli is için CPU hafızaya degisik yollardan erisme ihtiyacı duyar. Sizlerde programlarınızı yazarken CPU’nun hafızaya nasıl erisecegini yazdıgınız kodlarla belirtmek zorundasınız. Assembly dilinin bir basamagı olan adresleme modları da bu konuları kapsıyor ve bence iyi bilinmesi gereken bir konu.
Baslıca adreslemeler:



Register (Kaydedici) adreslemesi : Adından anlasılacagı gibi kaydediciden kaydediciye yapılan islemlerde bu adresleme modları kullanılır. En hızlı adresleme modu’dur, çünkü islem hafızada (Bellekte) degil islemcinin içinde gerçeklesir



mov eax, ebx ; EBX teki degeri EAX’e kopyalar
mov dl, al ; AL teki degeri DL’ye kopyalar (Açılımları yukarda söylemistik)
mov esi, edx ; EDX teki degeri ESI’ya kopyalar

Kaydedici adreslemede en çok dikkat etmeniz gereken husus hedef ve kaynagın boyutlarıdır. Örnegin 16 bitlik bir kaydediciden 8 bitlik bir kaydediciye tasıma yapılamaz!

mov cx, al ; Yanlıs kullanım, AL(8 bit) ile CX(16 bit) esit boyutta degil.

Hafıza bölgesi adreslemesi : Bu adresleme ile register hafızanın herhangi bir bölgesi isaretlenir. Bunun için MOV komutu yerine LEA (ilerde bahsedecegim)komutunu kullanabiliriz. MOV komutu registere verilen degeri yükler yada adresler. LEA komutu da aynı isi yapar. Ancak MOV komutundan önemli bir farkı vardır. Verdiginiz yerdeki degeri degil adresi yükleme yapar. Örnegin:

debug 'Yazi1',01

lea eax, debug seklinde verilince EAX registere 'Yazi' degiskeninin degeri degil bulundugu yerin adresi yüklenir. Böylece biz bu verinin basından itibaren istedigimiz gibi çalısma yapabiliriz.

Dolaysız adresleme :Bu adresleme registerler arasındaki degerlerin hafıza adresi olarak kullanılması ile olusan adreslemedir. Buna göre elimizde hiçbir deger yok sadece registerler vardır.

mov dword ptr [esi] ,eax =EAX deki degeri-ESI ile isaretlenen 32 bit hafıza bölgesine yaz
mov byte ptr [eax],bl = Aynı sekilde fakat burada ki deger 8 bit
mov dword ptr [esi],ebx =İlk örnek ile aynı



Burada su ana kadar bahsetmedigim birkaç kelime var onları anlatmak istiyorum arkadaslar.Örnegin byte ptr ve [ ] parentez simdi bunları kısaca açıklayacagım.

byte ptr : Açılımı arkadaslar (byte pointer) demektir.Eger yükleyeceginiz deger 1 byte (8 Bit) cinsinden bir deger ise bunu islemciye bildirmek zorundasınız ,aksi takdirde hata verir.

word ptr : Bu da arkadaslar (word pointer) anlamındadır.Ve 16 bittir.Yükleyeceginiz deger16 bitlik ise yine CPU ya bildirmek zorundasınız…

dword ptr : Bunun açılımı da arkadaslar (double word pointer) demektir ,yani 16 bitlik 2 sayı anlamındadır.Dogal olarak da 32 bitlik (4 bayt) lık bir degeri temsil eder.

[ ] Parentez : Bu ise arkadaslar kullanıldıgı yerin bir hafıza (bellek) adresi oldugunu gösterir.Bir [ ] parentez görürseniz o gösterilen yerin hafıza adresi oldugunu bilin..



Dolaylı Adresleme :Bu adreslemede arkadaslar ileride görecegimiz PUSH ve POP komutuna benzer olarak istenilen bir hafıza adresine saklama islemi yapılır. Bu bir register olabilecegi gibi bagımsız bir degerde olabilir.Örnegin :



mov dword ptr [deneme],ebx

mov word ptr [00364010] ,4252h



Böylece Registerler ve adreslemeler konusunu da bitirmis oluyoruz.Ama siz baska makalelerde okuyarak bilginizi saglamlastırın derim çünkü degisik kaynaklar her zaman iyidir ama bu kadar anlasılır olmayabilir J.Bundan sonra stack olayına da deginip ,komutlara geçecegiz.Stack olayı da iyi bilinmeli ve anlasılmalı arkadaslar bu nedenle buna da deginmek istiyorum.Bu arada bugün Mübarek Kadir gecesi Allah C.C tekrarını nasip eder insallah.



STACK ( YIĞIN ) NEDİR :



Gelelim arkadaslar Stack dedigimiz Yıgın konusuna.Bu konuda oldukça basit bir konu yeter ki bu yazdıklarımı dikkatli okuyun.simdi program yazan arkadaslar bilirler ,program yazarken bir degisken kullanırız.Mesela deriz ki; sayi= 24 bu bizim degiskenimizdir.Ve degistirilmedigi sürece hep 24 degerini saklayacak.Ama biz bu degiskene baska degerlerde almak ve 24 degerinin de kaybolmamasını istiyoruz.İste böyle bir durumda CPU bilgileri geçici olarak saklamak için hem registerleri hem de stack dedigimiz bu bölgeyi geçici yerlesim bölgesi gibi kullanır.Yani bilgilerimizi geçici olarak bu yıgına atar ve geri alır.Kısaca Stack, bilgilerin geçici olarak depolandıgı bir bölümdür deriz.

Bu yıgına giden bilgiler arkadaslar word uzunlugunda olup en az 2 byte (16 bit) ‘dir.Bu stack alanının bilgisini SP (Stack Pointer) tutar ve buraya gelen verilerin uzunluguna göre SP kendi degerini azaltır.Buradan degerler geri alındıgında ise SP kendi degerini alınan verinin uzunlugu kadar artırır.Bu biraz karmasık görünebilir ama degil çünkü biraz sonra bunu da bir örnekle anlatacagım .Bu yıgına veriler PUSH ve POP komutları ile atılır ve geri alınır.Atarken PUSH komutunu ,alırken de POP komutunu kullanırız.Bunları komutlar bölümünde inceleyecegiz zaten.

Gelelim simdi SP in veri alırken degerini azaltması olayına.Arkadaslar simdi bir çok bölmelerden olusan bir kitaplık düsünün (Bu bizim Satck ‘ımız yani yıgın bölgemiz).Bu kitaplıgımız bos haliyle 100 adet kitap alabiliyor.Biz bu kitaplıga tutar da,5 adet kitap korsak ne olur?Kitaplıgımızın %5 ‘i dolmus olur ,yani bos alanı %95 ‘ e düsmüs yani azalmıs oldu degil mi.Kitap alabilme yeri azaldı.İste Stack ‘ta veri aldıkça bos olan yerleri azalıyor.simdi anladınız degil mi.

NOT : Birde unutmadan arkadaslar bu stack’a atılan veriler ,en sondan baslayarak geri alınır.Yani Son giren veri ilk çıkar.söyle diyelim hani biz kitaplıga 5 adet kitap koymustuk ya,iste bu kitapları geri alırken de ilk önce 5. kitabı sonra 4. sonra 3.-2. ve 1. kitabı alabiliriz.Stack ta da bu böyledir.Tıpkı iç içe açılan For –next döngüsü gibi.En son açılan döngü ilk önce kapatılır. VB ‘ ci oldugum için aklıma bu örnek geldi.



Evet arkadaslar bu konuyu da bitirdik .Komutlar bölümün de görüsmek üzere.Saygı ve sevgilerimle



Cevapla