ADuC841 Mikrodenetleyicisi - 8051 MimarisiBlog YazılarGömülü Sistemler

Assembly ile ADuC841 – [5] ALT PROGRAM, YIĞIN VE SP SAKLAYICISI

ALT PROGRAM, YIĞIN VE SP SAKLAYICISI

Görsel Rehber

    Simülasyon

5.1 Alt Program Nedir? Neden Kullanılır?

Bir program yazarken aynı işlemi birden fazla yerde gerçekleştirmemiz gerekebilir. Bu kod bloğunu her ihtiyaç duyulan yere tekrar tekrar yazmak iki önemli probleme yol açar:

  • Program hafızasının şişmesi: Aynı kod her yere kopyalanır, mikrodenetleyicinin sınırlı ROM/Flash alanı gereksiz yere harcanır.
  • Bakımın zorlaşması: Kodda bir hata bulunduğunda tüm kopyaların tek tek güncellenmesi gerekir.

Çözüm şudur: Tekrarlanan kod bloğunu bir kere yazıp, ihtiyaç duyulduğunda o bloğa dallanmak. Bu bloğa alt program (subroutine) denir.

Alt program çağırma ve dönüş komutları şunlardır:

Komut Açıklama Hafıza Kullanımı Kapsam
acall <alt program ismi> Alt program çağrısı 2 Byte 2 kByte blok içi
lcall <alt program ismi> Alt program çağrısı 3 Byte Tüm 64 kByte
ret Alt programdan çıkış 1 Byte

Alt program, ilk ret komutuyla karşılaşana kadar çalışmaya devam eder. ret komutu çalıştığında, program akışı tam olarak acall veya lcall komutunun hemen bir altındaki satırdan devam eder.


Kritik Uyarı: Ana program akışı, acall veya lcall komutları kullanılmadan kontrolsüz biçimde alt program koduna girmemelidir. Bu durumda ret komutu yığında geçersiz bir adres bulur ve program tamamen çöker — sebebi aşağıdaki bölümlerde açıklanmaktadır.


Örnek: Temel Alt Program Yapısı

Akış açıklaması:

  1. acall p1_yaz komutu çalışır → program p1_yaz etiketine sıçrar. Geri dönüş adresi yığına otomatik kaydedilir.
  2. ret komutu çalışır → yığından dönüş adresi okunur, program acall‘dan sonraki satırdan (mov A, #AAh) devam eder.

5.2 SP Saklayıcısı (Stack Pointer — Yığın İşaretçisi)

SP (Stack Pointer), yığının (stack’in) o an en tepesini gösteren özel bir SFR’dir (Özel Fonksiyon Saklayıcısı). 8051 mimarisinde 8-bit genişliğindedir.

Reset sonrasında SP = 07h değerini alır.

Yığın 8051’de yukarı doğru büyür:

  • Her PUSH işleminde → SP önce 1 artırılır, ardından veri o adrese yazılır.
  • Her POP işleminde → veri önce okunur, ardından SP 1 azaltılır.

SP iki kritik görevi yerine getirir:

  1. Dönüş adresini saklamak: acall / lcall çalıştığında program, alt programdan döndüğünde nereye gideceğini SP’nin gösterdiği RAM adresine yazar.
  2. Geçici veri saklamak: Programcı push / pop komutlarıyla saklayıcı değerlerini geçici olarak yığına alabilir.

Bellek görünümü — Reset sonrası (SP = 07h):


Dikkat — SP Başlangıç Değeri: Reset sonrası SP = 07h, Bank 0 saklayıcılarının (00h–07h) tam üstüne işaret eder. Eğer programda Banka 1 (08h–0Fh) veya daha üstü saklayıcı bankaları kullanılıyorsa, yığın bu değerlerin üzerine yazabilir. Bu nedenle programın başında SP’yi açıkça güvenli bir bölgeye taşımak gerekir:


5.3 Alt Programdan Ana Programa Dönüş Adresine Donanım Tarafından Hesaplanması

ACALL komutu

ACALL komutu program hafızasında 2 Byte yer kaplar. Çağrılacak alt program, acall komutunun bulunduğu 2 kByte’lık blok içinde olmalıdır.

acall çalıştığında donanım otomatik olarak şu işlemleri yapar:

Neden önce PC+2? ACALL 2 baytlık bir komuttur. Komut işlendiğinde PC zaten bir sonraki komutun adresini göstermektedir. Bu adres “geri döneceğimiz yer” olarak yığına yazılır.


LCALL komutu

LCALL komutu program hafızasında 3 Byte yer kaplar. Alt program 64 kByte’lık belleğin herhangi bir adresinde olabilir. Çalışma mantığı acall ile tamamen aynıdır; tek fark PC’nin 3 artırılmasıdır:


RET komutu

RET komutu yığından 2 byte okuyarak PC’yi geri yükler ve SP’yi 2 azaltır:


Tam Örnek: acall + lcall + ret (PC ve Yığın Takibi)

Adım adım yığın ve PC durumu:

Adım Komut PC SP RAM[08h] RAM[09h]
Başlangıç 0203h 07h xxh xxh
acall alt1 çalıştı acall 1A02h 09h 05h 02h
ret (alt1) çalıştı ret 0205h 07h 05h 02h
lcall alt2 çalıştı lcall 2B3Ch 09h A5h 03h
ret (alt2) çalıştı ret 03A5h 07h A5h 03h

5.4 İç İçe Alt Program Yapısı

Bir alt programın içinden başka bir alt program çağrılabilir. Buna iç içe (nested) alt program denir. Her yeni çağrı yığına ekstra 2 byte yazar.

Örnek: alt1 içinden alt2 çağrısı

İç içe çağrılarda yığın büyümesi:

Durum SP Değeri Açıklama
Reset sonrası 07h Yığın boş
acall alt1 çalıştı 09h 2 byte eklendi (dönüş: 0205h)
lcall alt2 çalıştı 0Bh 2 byte daha eklendi (dönüş: 1B23h)
ret (alt2) çalıştı 09h 2 byte silindi
ret (alt1) çalıştı 07h 2 byte silindi, yığın boş

 Dikkat: Her iç içe çağrı yığına 2 byte ekler. Dahili RAM yalnızca 256 byte’tır. Gereksiz derinlikte iç içe çağrıdan kaçınılmalıdır; yığın taşarsa program çöker.


5.5 PUSH ve POP Komutları

Bütün 8051 ürünlerinde yığın (stack) hafıza, tümdevre-üstü RAM’da yer alır ve yukarıya doğru büyür.

PUSH komutu: Önce SP’yi 1 artırır, sonra SP ile işaret edilen hücreye bir byte kopyalar.

POP komutu: PUSH işleminin tersini gerçekleştirir. SP ile işaret edilen hücreden bir byte okur ve SP’yi 1 azaltır.

Komut Sözde Kod Adresleme Modu
push <kaynak> SP ← SP+1 ; RAM[SP] ← kaynak Doğrudan (Direct)
pop <hedef> hedef ← RAM[SP] ; SP ← SP-1 Doğrudan (Direct)

Neden PUSH/POP kullanılır? Alt program çalışırken ana programın kullandığı saklayıcılar (A, B, PSW vb.) bozulabilir. push ile bu değerleri yığına saklayabilir, alt program bitince pop ile geri yükleyebilirsiniz.

Örnek: Saklayıcı Koruma


LIFO Kuralı — En Önemli Kural: Yığın LIFO (Last In, First Out — Son Giren İlk Çıkar) yapısına sahiptir.

push ACCpush Bpush PSW sırasıyla itildiyse, mutlaka pop PSWpop Bpop ACC sırasıyla çekilmelidir.

Sıra bozulursa yanlış değerler yüklenir ve program hatalı çalışır.


 Not: PUSH ve POP komutları, saklayıcıları belirlemek için yalnızca doğrudan (direct) adresleme modunu kullanır. Yığının kendisine ise SP saklayıcısını kullanarak dolaylı adresleme ile erişilir. Bu yüzden yığının Yüksek 128 bölümde yer almamasına dikkat edilmelidir. Yüksek 128 olmayan ürünlerde (SP bu bölgeye işaret ederse) PUSH ile yazılmak istenen byte’lar kaybolur, POP ile okunan byte’lar ise belirsizdir.


5.6 Program Çökmelerinin Olası Nedenleri

Alt programdan çıkılıp ana programa dönülürken, dönüş adresi donanım tarafından SP içeriğinden okunarak PC’ye yüklenir. Bu değerin hatalı hesaplanması durumunda program akışı bozulur. Buna program çökmesi denir.

Program çökmesinin 3 olası nedeni vardır:


Neden 1 — SP’nin Kullandığı Hafıza Alanına Kontrolsüz Erişim

Programcı, yığın alanı olarak ayrılmış RAM bölgesine doğrudan bir mov komutuyla veri yazarsa, yığındaki dönüş adresi bozulur.


Neden 2 — PUSH ve POP Komutlarının Hatalı Kullanılması

2.1 — pop yapılmadan ret:

Alt programda push kullanılıp karşılığı pop yapılmadan ret çalışırsa, SP doğru konumda değildir. ret, yığında dönüş adresi yerine PUSH edilen veriyi okur.

2.2 — push yapılmadan pop:

Benzer şekilde, gereğinden fazla pop yapılırsa SP çok azalır ve ret yanlış byte’ları okur. Her push için mutlaka eşleşen bir pop olmalıdır.


Neden 3 — SP’nin Reset Sonrası Yanlış Bölgeye İşaret Etmesi

Reset sonrası SP = 07h’dir. Bu değer, Banka 0’ın son byte’ının (R7) hemen üstüne işaret eder. Programda Banka 1 (08h–0Fh) veya daha yukarısı kullanılıyorsa, yığın bu saklayıcıların üzerine yazar.

Ayrıca bazı programlarda SP, programın başında mov sp, #7Ah gibi bir komutla yanlış bir bölgeye kaydırılır. Bu bölgede gerçek bir RAM yoksa (veya başka veriler için ayrılmışsa), yığın taşması yaşanır.


Örnek — SP Başlangıç Değeri Hatası:


5.7 Yığın İşaretçisi (Stack Pointer, SP) — ADUC841 Genişletmesi

Standart INTEL-8051 ve INTEL-8052 mimarisinde SP 8-bit genişliğinde olup yalnızca dahili 256-byte RAM’i (00h–FFh) adresleyebilir.

ADUC841 mikrodenetleyicisinde ise CFG841 SFR’inin 7. biti olan EXSP biti setlenerek SP 11-bit genişliğine çıkarılabilir.

  • EXSP = 0 (varsayılan): SP 8-bit, standart 8051 gibi çalışır.
  • EXSP = 1: SP 11-bit olur. SP’nin düşük 8-bit’i SP SFR’inde, yüksek 3-bit’i ise SPH SFR’inde tutulur. Adreslenebilecek alan 0000h – 07FFh (2048 Byte) olur.

CFG841 Saklayıcısı

Bit İsim Açıklama
7 EXSP Setlendiğinde 11-bit SP aktif olur. Temizlendiğinde standart 8-bit SP çalışır.
6 PWPO P3.6 ve P3.7 pinleri PWM çıkışı olarak atanır.
5 DBUF Dahili DAC çıkış tamponları bypass edilir.
4–2 EPM2, EPM1, EPM0 PWM saat frekansı bölme faktörünü belirler.
1 MSPI SPI biriminin MISO, MOSI, SCLOCK fonksiyonlarını P3.3, P3.4, P3.5 pinlerine atar.
0 XRAMEN Dahili XRAM kullanıma açılır ve harici veri hafızasının alt 2 kByte’ına yerleştirilir.

 Not: CFG841 SFR’i bit adreslenemez. Bu nedenle setb CFG841.7 gibi bit komutları kullanılamaz. Bunun yerine orl komutuyla ilgili bit setlenir.


11-bit SP Ayarlama Örneği


8-bit SP ile 11-bit SP Karşılaştırması

Özellik 8-bit SP (EXSP=0) 11-bit SP (EXSP=1)
Adres aralığı 00h – FFh 0000h – 07FFh
SP kaydedildiği yer Yalnızca SP SFR SP (düşük 8-bit) + SPH (yüksek 3-bit)
Yığın alanı 256-byte dahili RAM 2048-byte (RAM + XRAM)
Kullanım amacı Standart uygulamalar Derin iç içe çağrılar, büyük yığın ihtiyacı

PWM Frekansı Bölme Tablosu (EPM2–EPM0 bitleri):

EPM2 EPM1 EPM0 Bölme Faktörü
0 0 0 32
0 0 1 64
0 1 0 128
0 1 1 256
1 0 0 512
1 0 1 1024

ÖZET — Hızlı Başvuru Tablosu

Komut / Kavram Ne Yapar? Dikkat Edilecek Nokta
acall Alt program çağrısı (2 Byte, 2kB kapsam) Alt program aynı 2kB blokta olmalı
lcall Alt program çağrısı (3 Byte, 64kB kapsam) Her yerde kullanılabilir
ret Yığından dönüş adresini okur, döner Yığın bozuksa çökme kaçınılmaz
push SP++ → RAM[SP] = veri Her PUSH için mutlaka bir POP olmalı
pop veri = RAM[SP] → SP– LIFO sırası korunmalı
SP Yığının tepesini gösteren 8-bit SFR Reset = 07h; programda açıkça ayarlanmalı
EXSP (CFG841.7) SP’yi 11-bit’e genişletir (ADUC841) Bit adreslenemez; orl ile setlenir

 Dipnot: ret komutu her zaman alt programların sonunda bulunmalıdır. Kesme hizmeti alt programlarından (ISR) çıkarken ise reti komutu kullanılır; ret değil. Bu iki komut birbirine karıştırılmamalıdır.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Başa dön tuşu