ARM Assembly - Branch and Control | VisUAL2 ile ileri ARM Assembly Örnekleri

Transistörlerimizi oluşturduk, Logic Gate'leri tanıdık,

Sonra onları kullanarak 4 Bit'lik toplayıcı (ALU) yaptık,

Sonrasında VisUAL2'nin de desteği ile, ARM Assembly'e giriş yaptık.

Şimdi sırada, Assembly'i bir adım daha öteye taşımak var.

Önceki Assembly konusunda, Assembly dillerine giriş yapmış, temel öğelerden bahsetmiştik. Ben, Assembler olarak ARM'yi seçmiştim. Zira yeni trend ARM. 

Önceki makalemi, kısaca bir başlığa değinerek bitirmiştim: Branch and Control

Branch and Control

Assembly dilinde if, while, for gibi operatörler yoktur. Bunların yerine conditional branching denen yöntem uygulanır, ancak bu başka bir yazının konusu olsun.


Bir başka yazının konusu olsun diye kısa kesmiştim ve bugün, o yazının vakti geldi.

ARM Assembly - Branch and Control

Python, C, Javascript gibi alıştığımız ve günlük hayatta sıklıkla kullandığımız dillerde, ifelseelse if ya da elif gibi ifadeleri çokça görmüşsünüzdür, kullanmışsınızdır. Kabaca "Conditions and Statements" olarak ifade edilen bir durum, temelinde şu ilkeye dayanır. Çok detayına girmeden açıklamak gerekirse, bu kalıplar belirli koşullarda (conditions), belirli durumların (statements) ortaya çıkmasına sağlar. Koşullar genelde bir değişken olurken, durumlar ise bir kod parçası, fonksiyon ya da çıktı olur.

Programlamaya yeni başlayan ve daha fazla detaylara inmek isteyenler için, İngilizce bir makale: Statements

Önceki yazımda da bahsettiğim gibi, ARM alıştığımız dillerden farklı karakterlere sahiptir. Bu karakterlerden biri de, alıştığımız dillerde olan ifelsewhile gibi operatörleri barındırmamasıdır. Bunun yerine, benzer işlevi görmesi için, farklı ama kolay bir yol kullanılır.

Programın çalışma süresi boyunca, genellikle atlamalar (branching) yaparak veya yalnızca bir koşul geçerli olduğunda, belirli bazı talimatlar uygulayarak programın akışını kontrol etmek, için koşulları (conditions) kullanırız. Koşul, CPSR (Current Program Status Register) yazmacındaki (register) belirli bir Bit'in durumu olarak tanımlanır. Bu Bit'ler, bazı talimatların sonucuna göre zaman zaman değişir.

Örneğin, iki sayıyı karşılaştırdığımızda ve bunların eşit olduğu ortaya çıktığında, Sıfır bitini (Z = 1) tetikleriz, çünkü işlemcinin içinde şunlar gerçekleşir: a - b = 0. Bu durumda, EQual koşulumuz sağlanmış olur. İlk sayı daha büyük olsaydı, Büyüktür koşuluna sahip olurduk, tersi durumda ise Küçüktür koşuluna. Ve bunların dışında, bir sürü koşul vardır.

Aşağıdaki tablo, mevcut koşul (condition) kodlarını, anlamlarını ve test edilen durumları gösteriyor:

Koşul (Condition) koduAnlamıKontrol durumu
EQEqualZ==1
NENot EqualZ==0
GTSigned Greater Than(Z==0) && (N==V)
LTSigned Less ThanN!=V
GESigned Greater Than or EqualN==V
LESigned Less Than or Equal(Z==1) || (N!=V)
CS or HSUnsigned Higher or Same (or Carry Set)C==1
CC or LOUnsigned Lower (or Carry Clear)C==0
MINegative (or Minus)N==1
PLPositive (or Plus)N==0
ALAlways executed
NVNever executed
VSSigned OverflowV==1
VCNo signed OverflowV==0
HIUnsigned Higher(C==1) && (Z==0)
LSUnsigned Lower or same(C==0) || (Z==0)


Bunlara ek olarak, CPSR (Current Program Status Register) tablosuna da ihtiyacımız olacak. Bu registerlar, programdaki mevcut koşulu kaydetmeyi yarar:

DeğerAçıklaması
N
(Negative)
Talimatın sonucu negatif bir sayı verirse etkindir.
Z
(Zero)
Enabled if result of the instruction yields a zero value.
C
(Carry)
Talimatın sonucu sıfır değeri verirse etkindir.
V
(Overflow)
Komutun sonucu, 32 bit ikinin tümleyeni ile temsil edilemeyen bir değer verirse etkinleştirilir.
E
(Endian-bit)
ARM, küçük endian veya büyük endian'da çalışabilir. Bu bit, küçük endian için 0'a veya büyük endian modu için 1'e ayarlanır.
T
(Thumb-bit)
Bu bit, Tumb State geçerliyse ayarlanır ve ARM State etkinken devre dışı bırakılır.
M
(Mode-bits)
Bu bitler, geçerli ayrıcalık modunu (USR, SVC, vb.) belirtir.
J
(Jazelle)
Bazı ARM işlemcilerin donanımda Java bayt kodu yürütmesine izin veren üçüncü yürütme durumu.


Şimdi ise gelin, örnek bir kod yazalım:

Assembly:
mov     r0, #2
cmp     r0, #3
addlt   r0, r0, #1
cmp     r0, #3
addlt   r0, r0, #1


Ve satır satır anlamaya çalışalım:

  • mov r0, #2: önceden aşina olduğumuz bir kod, 2 rakamını r0 registerına kaydediyoruz,
  • cmp r0, #3: yeni bir kod. r0 registerındaki rakamı, 3 rakamı ile karşılaştırıyoruz. 2 3'ten küçük olduğundan, CPRS tablosunda bahsettiğimiz N (Negative) registerı etkin hale geliyor. (2 - 3 = -1)
  • addlt r0, r0, #1: add komutunu biliyoruz ancak lt diye bir ek eklenmiş. Bu ek, programlamadan aşina olduğumuz < eki aslında, yani küçüktür. Ancak burada biraz farklı bir mantıkla çalışıyor. Normal bir programda 2 < 3 yazarız ve tek satırda karşılaştırma biter. Ancak burada karşılaştırmaya karar verecek olan, bir üst satır yani cmp komutu. Hatırlarsanız orada N registerı aktif olmuştu. Yani, 2 3'ten küçüktü.
    • addlt komutunun yaptığı şey, verilen sayı küçüktür ifadesini karşılıyorsa, sayıları toplamak. burada r0'daki sayı ve 1 rakamı, komut için girdi olarak verildiğinden, program kabaca 2 rakamı bir arttırmış olacak.
  • Sonraki iki adım da, önceki iki adımı tekrar ediyor. Ancak bir fark var. addlt kısmına geldiğinde, komut çalışmayacak zira öncesinde 2'ye 1 eklediğimiz için, r0'daki sayı artık 3 oldu. Bu nedenle N registerı aktif olmayacak ve dolayısıyla da lt komutu çalışmayacak.
  • Bu nedenle program, burada çalışmayı durdurur.
kod_1.PNG



Bu yaptığımız aslında, alıştığımız dillerdeki for döngüsünün içinde, if ve else kullanmaktan farksız bir durum. Aslında aradaki farkın temeli de burada anlaşılıyor.

Condition kodlarını ve CPSR registerlarını kullanarak, farklı durumlara göre programımızın yol almasını sağlayabiliriz. Bunu kısaca bir tabloyla gösterelim: (Ben çizdim ancak çok temel bir tablodur, internette benzerlerini hatta daha detaylılarını bulabilirsiniz)

Dosya_000.png



Böylece if veya for / while operatörlerinin işlevlerini, Assembly'de yerine getirebiliriz.

for ve while detayına fazla girmek istemedim, zira kafanızın fazla karışmasını istemedim. Bu yazıdaki temel amacım, öncesinden eksik kalan noktayı tamamlamaktı. 

Okuduğunuz için teşekkür ederim.

İbrahim Özdemir, Ocak 2021

Comments