Bu site emekli olmuştur. Arşiv amaçlı olarak BT AKADEMİ sponsorluğunda yayın hayatına devam etmektedir.




C#nedir?com
 
YAZAR HAKKINDA
Eren Erener
Eren Erener
http://www.csharpnedir.com/
İletişme geçmek için tıklayın.
12 Makalesi yayınlanmakta.
Yazar hakkında detaylı bilgi için tıklayın.
Yayınlanan diğer makaleleri için tıklayın.
İlgili etiketler: .stack alanina alanini assembly bitlik dallanma dilinde hafiza kaydedicileri kullanilir. memory programlar saklamak segment yiginda X86 Assembly Eren Erener
 
YAZI HAKKINDA
Türü : Makale
Serbest Köşede C#nedir?com üyelerinin hazırladıkları yazılar yayınlanır. Bu yazılar editör incelemesine girmeden yayınlanır.
Seviyesi : Orta
Kategori : X86 Assembly
Yayınlanma Tarihi : 24.5.2006
Okunma Sayısı : 60821
Yorum Sayısı : 4     yorum yaz
Site İçi AramaSİTE İÇİ ARAMA
Üye Girişini AçÜye GİRİŞİ
Üye girişi için tıklayın.
Kullanıcı Adı
Şifre
 
Beni her zaman hatırla
Bir hafta boyunca kullanıcı bilgilerinizi kullanıcı çıkışı yapana kadar hatırlar. (Paylaşılan bilgisayarlarda önerilmez.)
 
Şifremi / Kullanıcı Adımı unuttum.
 
.net TV RSS Serbest KÖŞE (?)
Serbest Köşede C#nedir?com üyelerinin hazırladıkları yazılar yayınlanır. Bu yazılar editör incelemesine girmeden yayınlanır.
emre TAŞ
Silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
Makale Gönder Bende Yazmak İstiyorum
.net TV RSSBlogroll
Turhal Temizer
Conda install environment.yml Package 21.11.2024
Turhal Temizer
Mac OS/X Removing CUDA 21.11.2024
Burak Selim Şenyurt
Rust ile ECS Yaklaşımını Anlamak 21.11.2024
Burak Selim Şenyurt
Birlikte Rust Öğrenelim Serisi 21.11.2024
  Diğer Herşey
Sponsorlar
BT Akademi
Medya Portakal
Video Hosting Sponsoru
Csharpnedir.com bir Ineta üyesidir
Uzman Abi
Her Yönüyle C# - Sefer Algan
Stack Memory (Yığın Hafıza Bölgesi)
 
Kapat
Sayfayı Yazdır Sık Kullanılanlara Ekle Arkadaşıma Gönder MySpace Del.Ico.Us Digg Facebook Google Mixx Reddit StumbleUpon
Bu makalede stack (yığın) hafıza bölgesini anlatmaya çalışacağım.

Stack memory geçici değerlerin saklandığı bir hafıza alanıdır. Mikroişlemci SS:SP kaydedicileri ile bu hafıza alanına erişir. SS stack alanının segment adresini tutarken SP bu alandaki offsetleri işaret eder. Stack hafıza alanını kullanmama diye bir lüksümüz yok, bu makaleye kadar stack memory ile ilgili hiç bir komut yazmasakta, bu hafıza alanını yadığımız tüm programlar kullandı.

Bununla beraber stack memory’yi kendi isteklerimiz doğrultusunda da kullanabiliriz. Bunun için bir çok komut mevcuttur. PUSH, POP, CALL, RET  bunlardan bazıları ve bu makalede anlatılacaklar arasındadır.

LIFO

Mikroişlemci stack memory’yi diğer hafıza alanlarını adreslerken kullandığı yöntemden biraz daha farklı adresler. Öncelikle stack hafıza alanına yüklenen bilgiler LIFO (Last In First Out) yani ilk giren son çıkar yada ilk yüklenen bilgi en son alınır düzenine göre sıralanırlar.
Şekil 1 - Stack (Yığın) hafıza. Yukarıdaki şekilde kırmızı bloğu stack memory olarak düşünebilirsiniz. BU alanın büyüklüğünü kod yazarken .stack talimatı ile belirliyoruz, .stack 32, .stack 100h gibi. Geçici verilerinizi saklamak için ne kadar alana ihtiyacınız varsa o kadar stack tahsis edebilirsiniz. Yine yukarıdaki şekilde orijinal SP yığın boşken SP kaydedicisinin aldığı değerdir. Mesela .stack 32 diye direktif verdiyseniz SP=0020h ı gösterir. Yığına veri itildikçe SP’nin değeri azalır, bu değerler yığından çekildikçe SP artar. x86 mimarisinde yığın hafızaya 16 bitlik çalışma modunda 16 bitlik değerler, 32 bitlik çalışma modunda ise 32 bitlik değerler saklayabilirsiniz. PUSH ve POP komutları Stack memory’de verilerinizi saklamak için kullanılan komutlardır. Stack’ta saklanan veriler veya adres bilgileri için genelde "stack’a itilen" kelimeleri kullanılır. Stack’tan geri alınan veriler içinse "stack’tan çekilen" kelimesi kullanılır. Özetle PUSH komutu stack’a bir veriyi itmek için, POP ise verileri çekmek için kullanılır. Yığın hafıza alanını etkileyen komutların genel kullanım formatları aşağıdaki gibidir;         push    reg16
        pop     reg16
        push    reg32                   (**)
        pop     reg32                   (**)
        push    segreg
        pop     segreg                  (CS hariç)
        push    mem
        pop     mem
        push    imm                     (*)
        pusha                             (*)
        popa                               (*)
        pushad                            (**)
        popad                             (**)
        pushf
        popf
        pushfd                             (**)
        popfd                              (**)

(*)- Sadece 80286 ve sonrası işlemcilerde.
(**)- Sadece 80386 ve sonrası işlemcilerde. En çok kullanılan komutlar PUSH ve POP komutlarıdır. PUSHA ve PUSHAD tüm kaydedicileri yığında saklamak amacıyla kullanılır, POPA ve POPAD ise saklanan bu kaydedicileri geri almak için kullanılır. PUSHF, PUSHFD bayrak kaydedicisini saklamak POPF ve POPFD ise bunları geri almak için kullanılır. Peki neden kaydedicilerin içeriğini saklamak durumunda kalalım? Programcıların programlarını düz mantıkla yazmadığını biliyorsunuz, modüler programlama teknikleri kullanılmazsa 30-40 satırdan sonra kaynak kod anlaşılmaz hale gelir. Günümüzdeki programlar onbinlerce hatta milyonlarca komut satırından meydana geliyor. Bunun için programı parçalara ayırmak, modüller hazırlamak şart. Yüksek düzeyli programlama dillerinde kullanılan, sınıf, fonksiyon gibi kavramlar hep bu amaç için türetilmiştir. Assembly dilinde CALL ve RET komutlarıda bunu amaçlar. Hatta C dilinde ve birçok programlama dilinde fonksiyon çağrımlarının assembly dilindeki tam karşılığı CALL komutudur. İster assembly dilinde call komutunu kullanın isterseniz C dilinde bir fonksiyonu çağırın, dallanma işlemi gerçekleşmeden önce geçici parametreler stack’ta saklanır. CALL ve RET Komutları Bu komutları anlatmadan önce assembly dilinde prosedür (procedure) mantığını kavramanız lazım. Bir örnekle prosedürleri anlayalım.

Şekil 2 - Prosedürler kullanılarak yapılmış bir kaynak kod.. Kaynak kodu buradan indirebilirsiniz. Bu program bir önceki makaledeki string komutlarına örnek olmakla beraber biz burada sadeve CALL ve RET komutlarını inceleyeceğiz. Program çalıştığında komut isteminden bir yazının girilmesini ister, şayet yazıyı oluşturan karakterler büyük harfli ise bunları küçük harfe dönüştürür. Programda üç tane prosedür bulunmakta ve ana prosedüre baktığınızda klasik kodlar olan segment ayarlama ve dosa dönüşün dışında sadece CALL komutlarını görüyorsunuz. Ana prosedürden 3 kere alt prosedürlere dallanma gerçekleşiyor. Her dallanma sırasında geri dönüş adresi yığında saklanır. Alt prosedürlerden dönerkende ret komutu ile bu adres geri yüklenir. Şayet dallanma bir başka segmente tapılıyorsa CS ve IP, buradaki gibi aynı segment içindeyse sadece IP yani offset adresi yığında saklanır. Offset ve segment adreslerinin 2 byte olduğunu düşünecek olursanız bunun stackın yapısınada uygun olduğunu anlarsınız. Yığın hafıza yada stackın kullanılmadığı bir program yok gibidir. Tüm kesmeler (bunlarda bir çeşit alt prosedür gibi düşünüle bilir) çağrılmadan önce, o anki CS ve IP ayrıca tüm kaydediciler yığında saklanmak zorundadır. Aksi halde geri dönüş yapıldığında alt prosedürün değiştirdiği kaydediciler ile karşılaşılır, hatta bu bile mümkün olmaz çünkü mevcut CS ve IP saklanmadan geri dönüş söz konusu değildir. Satırlar yığın hafızayı anlatmakta biraz yetersiz kalıyor olabilir, bu konuyu anlamamış olabilirsiniz diye sizlere birde video hazırladım. Yukarıdaki programın örnek alındığı videoyu buradan download edip izlediğinizde sanırım problem çözülecek :) Şunları hatırlamakta fayda var; 1- Programlar genelde 3 adet hafıza alanından oluşur, bunlar code, data ve stack tır.
2- CPU bu alanlara adresleme yaparak erişir,
3- CPU CS ve IP kaydedicilerini kodlara erişip onları işlemek için,
4- DS, SI ve DI’yı değişkenlere datalara erişmek için,
5- SS, SP ve BP’yi yığın hafıza alanına erişmek ve biçimlendirmek için kullanılır. Örnek programımızdaki ana prosedür dışındada CALL komutunu kullanabilirsiniz, alt prosedürleri istediğiniz kadar çağırabilirsiniz. Fakat bir prosedür içinden kendini çağırırken dikkatli olmalısınız, yazacağınız kodlarla programın sonsuz döngüye girmesini engellemezseniz, "memory overflow" hatasından önce "stack overflow" hatasını alırsınız. Bu makaleyi iyice anlamak için mutlaka videoyu izleyin ve bu örnek programın kaynak kodlarını kendiniz derleyip çalıştırın ve bu programa başka prosedürler ekleyip onları başka prosedürlerden yada ana prosedürden çağırarak programı inceleyin. İyi çalışmalar... :)
Makale:
Stack Memory (Yığın Hafıza Bölgesi) Assembly ve X86 Programlama Eren Erener
  • Yazılan Yorumlar
  • Yorum Yaz
MAR
16
2010
Slm, Öncelikle bize bu makaleyi sunan ve diger tüm bilgileri bize ulastiran arkadaslara çok tesekkürler, Allah hepinizden razi olsun. Disarda yasadigim için Türkçem çok kuvvetli degil malesef. Bu makaleye kada yazilan çogu seyi anladim gibi, fakat asagidaki kod parçasini biraz daha detayli anlatan biri olursa beni çok sevidirir. Simdiden hersey için çok saolun. cld lea si, girdi+2 mov di, si mov cl, girdi+1
EKİ
21
2009
Hocam makalelerinize başka bir konuyu ararken tesadüfen rastladım. O kadar güzel bir anlatımı vardı ki okumaktan kendimi alamadım, ve X86 Assembly ile ilgili tüm makalelerinizi baştan sona okudum. Tek kelime ile Mükemmel! Makaleleri o kadar açık bir anlatımla ve özenle hazırlamışsınız ki okuyucunun anlamamasına imkan yok. Konunun özünü sizin sayenizde daha iyi anladığıma inanıyorum. Çok teşekkürler. Ellerinize sağlık.
HAZ
19
2006
Eren hocam, çok güzel bir makale yazmışsınız. Ellerinize sağlık.
Sayfalar : 1 
Yorum yazabilmek için üye girişi yapmalısınız. Üye girişi için tıklayın.
Üye değilseniz Üyel Ol linkine tıklayarak üyeliğinizi hemen başlatabilirisniz.
 
  • Bu Konuda Son 10
  • Eklenen Son 10
  • Bu Konuda Geçmiş 10
Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
Son Eklenen 10 Makale Yükleniyor
Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor