AVR Assembly -9- Branch (Dallanma) Komutları

Mikrodenetleyiciyi açıklarken program sayacından (PC) bahsetmiştik. Bu program sayacı sıfırdan (0x0000) başlayıp 0x3FFF’e kadar her komut işlendiğinde birer birer artıyor ve adreslediği hafızadaki makine kodunu mikroişlemci okuyup çalışmaya devam ediyordu. Bu durumda aynı kodu birden fazla kere işletmemiz gerektiğinde alt alta defalarca yazmamız gereklidir. Bu hem programı işin içinden çıkılmayacak kalabalıklığa sevk eder hem de hafızada gereksiz yere yer işgaline sebep olur. Bu yüzden program sayacına zaman zaman belli müdahaleler yapılıp programda ileri geri gitmek gerekir.

Biz de bir kitap okurken bazen kitapta “Bakınız” ibaresiyle belli sayfalar bize belirtilir. Hemen okuduğumuz sayfayı bırakıp o sayfaya atladıktan sonra kendi sayfamıza geri dönüp okumaya devam ederiz. Bu şekilde bir işin gerekliliği kaçınılmaz olduğu için mikroişlemci tasarımcıları dallanma komutlarını geliştirmiştir.

Branch komutları adından anlaşılacağı gibi daldan dala atlamayı gerçekleştirir ve programı belli dallara böler. Bu dallanma işlemi etiketler vasıtasıyla gerçekleştirilir.  C dilinde fonksiyonlar da aslında birer branch komutunun uyarlanmasından öte değildir. Bu dallanma komutları donanıma ait bir özellik olmakta fakat C dilinde bu özellik standartlaştırılmakta, kolaylaştırılmakta ve taşınabilir hale getirilmektedir. C dilinde bir fonksiyon adının aslında birer adres değeri olması bu yüzdendir.

Şimdi branch’e neden “dallanma” dedin diye çıkacak biri olacaktır mutlaka. 🙂 Şunu belirtmem gerekir ki braching’e “dallanma” karşılığını Türk Dil Kurumu’nun Bilgisayar Terimleri Karşılıklar Kılavuzu’ndan almış bulunuyorum.

AVR Assembly programlarken elimizde bir değer olsun ve bu değeri sürekli birer birer azaltma gereği duyalım. Değer sıfır olana kadar bu devam edecektir. Bu durumda dallanma komutları olmadan programımız oldukça uzun olacaktır.

Şimdi dallanma komutları kullanılmadan bir AVR programının nasıl yazılacağını görelim.

BRNE Komutu

BRNE komutu (branch if not equal) deyiminin kısaltımı ile BRNE halini almıştır. Bu komut SREG yazmacındaki sıfır (0) bayrağını kullanır ve bu bayrak biti bir (1) olmadıkça program akışını bir önceki etikete götürür. Eğer elde ettiğimiz değer sıfır olursa bu döngüden çıkılır ve program kaldığı yerden devam eder. Şimdi yukarıdaki aynı programı BRNE komutu ile yazalım.

Bu program öncelikle R16 yazmacına desimal 10 değerini yükleyecektir. Sonrasında Azalt: adında iki nokta “:” ile programcı tarafından etiket oluşturulmuştur. C dilinde de etiketlerden bahsedilse de kullanımı tavsiye edilmemektedir. Etiketlerin artması programı oldukça karmaşık ve işin içinden çıkılmaz yapacağı için C dilinde kullanmasak da Assembly ve BASIC gibi dillerde çoğu yerde etiketleri kullanmak zorunda kalırız. Assembly’de dikkat edeceğimiz noktalardan biri bu olmalıdır. Etikete istediğimiz bir adı verebiliriz.

DEC R16 ile R16’nın değerini ilk seferde bir azaltıp 9 yaparız. BRNE komutuna geldiğimizde BRNE işlemcinin durum yazmacını kontrol eder. Bu yazmaçta sonuç sıfır olmadığı için AZALT etiketine programı atlatır ve devam ettirir. Devamında yine DEC R16 komutu işletilir ve R16’nın değeri bir azaltmış olur. Değeri bir azaldığı için 8 olan sonuç yine sıfır bayrak bitini etkilemez ve BRNE AZALT ile tekrar AZALT: etiketine atlanmış olur. Bu atlamalar SREG yazmacındaki Z yani Zero bayrak bitinin bir (1) olmasına kadar devam eder. Bunun için de R16 yazmacının değerinin DEC ile kademeli olarak sıfıra kadar azaltılması gereklidir.

Dikkat etmeniz gereken bir nokta da programı döngüden çıkaracak bir durumun muhakkak olması lazımdır. Eğer buna dikkat etmezsek program sonsuz döngüye girecektir.

Dikkat ederseniz BRNE komutu donanımsal olarak sınırlandırılmıştır. Herhangi bir yazmaçtaki değer sıfır olduğunda döngüden çıkışmaktadır. 8 bitlik bir değerimiz olduğu için bir döngünün en fazla 255 kere döneceği ortadadır. Bu durumda döngü içinde döngü yaparak bu dönüm sayısını artırabiliriz. Şimdi 1000 kere çalışacak bir program yazalım.

Burada öncelikle döngülerden bağımsız olarak R16 yazmacına 10 değerini atadık. Bu sermaye olarak elimizin altında olacaktır. Sonrasında BIRINCI: adlı etiket ile büyük döngüyü açtık ve R17 yazmacına 100 değerini verdik. Döngünün içindeki döngünün esas aldığı değer bu olacaktır. DEC R17 komutu ile her çevirimde bir azalarak döngü dönmeye devam eder. Eğer R17 değeri sıfır olursa döngüden çıkılır ve R16 değeri bir azaltılır. R16 değeri bir azalında sıfır şartı sağlanmadığı için tekrar BIRINCI: etiketine program akışı atılmış olur. Bu durumda aşağıya inebilmek için tekrar yüz kere çalışmak zorunda kalacak ve en sonunda R16 yazmacındaki değeri bir azaltabilecektir. Bu durumda program 1000 kere çalışmadan bu döngüden çıkamaz hale gelir. Eğer yanlışlıkla sıfır sonucu verecek bir aritmetik işlemi dallanma komutunun öncesine koymazsak sıkıntısız çalıştırabiliriz. İki kere değil üç, dört kere de bunu yapabiliriz. Hatta milyonlarca defa döngü çalışabilir.

Dikkat edilirse bu dallanma komutu belli bir şarta bağlıdır. Şarta bağlı dallanma komutlarını aşağıdaki tabloda görebilirsiniz. Aynı mantıkta olduğu için hepsine örnek verme gereği görmüyoruz.

KOMUT İŞLEM AÇIKLAMA
BRLO C = 1 ise Döngü Eğer eldesiz değer elde edersek döngüden çıkar.
BRSH C = 0 ise Döngü Eldeli değer elde edersek döngüden çıkar. Bir diğer ifadeyle 255’den yukarı bir değer elde edersek.
BREQ Z = 1 ise Döngü Sıfırdan farklı değer elde edilirse döngüden çıkar.
BRNE Z = 0 ise Döngü Sıfır elde ettiğimizde döngüden çıkar.
BRMI N = 1 ise döngü Pozitif bir sayı elde ettiğimizde döngüden çıkar
BRPL N = 0 ise döngü Negatif bir sayı elde edilirse döngüden çıkar.
BRVS V = 1 ise döngü Taşma elde edilirse döngü devam eder.
BRVC V = 0 ise döngü Taşma elde edilmezse döngü devam eder.

 

Döngü şartlarının aritmetik işlemlere bağlı olduğunu fark edebilirsiniz. Biz C ile programlama yaparken yine bu makine komutları programa uyarlanarak döngüler kuruluyordu. Bu döngülerin karşılığının C dilindeki do..while ve for döngülerinin olduğunu söyleyebiliriz. Bir sonraki derste daha farklı dallanma yöntemlerinden bahsedeceğiz.

Bizi Facebook grubumuzda takip etmeyi unutmayın. Bilgili ve öğrenmeye hevesli bir topluluk oluşturmak istiyoruz.

https://www.facebook.com/groups/1233336523490761/

 

UYARI!!

Gökhan Dökmetaş

"Arduino Eğitim Kitabı" ve "Arduino ve Raspberry PI ile Nesnelerin İnterneti" kitaplarının yazarı. Başkent Teknoloji ve Dedektör Merkezi'nde Ar-ge Sorumlusu. Araştırmacı-Yazar.

You may also like...

1 Response

  1. rıdvan altun dedi ki:

    Dersler güzel ilerliyor, devamını bekliyorum.

    Bu arada teorik yerine biraz pratik bilgi eklerseniz güzel olur, butona tiklayinca yanan led gibi ufak örnekler.

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.