ARM – 3 Komut Setlerine Giriş
Arkadaşlar bu yazımızda nihayet ARM’da komut setlerini öğrenmeye başlıyoruz. Öncelikle size giriş niteliğinde bir kaç konu aktarmak istiyorum. ARM’da işletilen komutların hepsi geriye dönük uyumlu çalışır. Bunu açmak gerekirse teknoloji ilerledikçe ARM 5-6-7 gibi sürümler çıkardı baştan beri çıkarılan yeni sürümlere yeni komutlar eklenmesi gerekiyordu. Bunun için lütfen kodlarınızı yazmadan önce elinizde bulunan ARM işlencinin model ve seri numarasını iyi bilin. Bu numaraya bağlı olarak aşağıda yer alan komutların hangisini kullanabileceğinizi öğrenmiş olursunuz.
ARM Komut Seti Uyumluluk Tablosu
Komutlarımızın hangi sürümlerde geçerli olduğunu öğrendikten sonra komut setlerinin temel yapısına değinelim. Öncelik komutlar prefix ve postfix ekler alırlar. Örnek olarak Hafızanın bir bölümüne ulaşmak için prefix ve postfix komulara ihtiyaç duyulur.
- mem<data_size>[adress] şeklinde bir komut varsayarsak ;
- mem32[1024] burada 32 prefix 1024 ise postfix’dir. Yani 32 bitlik başlangıç adresi 1Kb olduğunu belli eder.
Arm komutları verileri register içinde işlerler. Bu yüzden verileri işlemeden önce mutlaka registerlara transfer edilmesi gerekmektedir. Bu bilgi bizim için çok önemlidir. Bunu yapmanın yolu hafızada load/store komutları kullanarak verinin yazmaçlara alınmasını sağlamaktır. ARM komutları genel olarak 3 veya 2 operand alırlar. Bunu bir örnek ile açıklamak gerekirse;
- ADD r0(rd),r1(rn),r2(rm)
- Komutu r2 ve r1 yazmaçlarının içindeki değerleri toplayarak sonucu r0 yazmacının içine atar. burada rd, rn ve rm değerlerini ARM1 adlı yazımızda gösterdiğimiz ilk fotoğrafta yer alan blok diyagramda hangi registerlar olduğunu göstermesi için ekledim. Buradan elde edilecek bilgi eğer komut setinde barrel shifter kullnmak istiyorsak bunu sadece rm işareti olan r2 yazmacında yapabiliriz.
ARM Veri İşleme Komutları
MOV Komutu : Mov komutu her mikroişlemcide olduğu gibi ARM mikroişlemcilerinde de bulunur. Kullanımı çok basittir. İşlem yapmadan önce register’a istenilen ilk değerlerin yüklenmesini sağlar. Kullanım yapısı şu şekildedir.
- <instruction>{<condition>} {S} Rd, N
- MOV r0, r1 veya MOV r0,5
- iki örnektede görüldüğü gibi R1 ve 5 ifadesi N değerine karşılık gelmektedir. Yani MOV komutu ile sabit bir sayı veya bir yazmaç değerini diğer bir yazmaça atabiliriz.
MVN Komutu : Mov komutunun yaptığı işlemin yanında sonucun değilini alır.
- MVN Rd,N yazarsak N içindeki değerin değilini alır yani sonuç olarak Rd değeri ~N e eşit olur.
Barrel Shifter : İlk yazılarımızda da değindiğimiz gibi komutlarımızın içinde barrel shifter kullanabiliriz. Bu işlemi yapabilmemiz için değerin Rm yazmacı içinde olması gerekir.( Bknz : ARM-1 Yazısı ilk Şekil) Bu kaydırıcı vasıtasıyla register içindeki değeri, komutun belirtildiği sini değiştirmeyecektir. Kısaca sonuçlar ALU’da işleme tabi tutulmadan önce barrel shifter vasıtasıyla ön işleme tutulurlar.
- MOV r7, r5, LSL #2 ; Bu işlemin sonunda r7 = r5*4 = (r5 << 2) olur.( Sayısal devrelerden hatırlarsanız bir sayıyı iki sola kaydırmak sayıyı 4 ile çarpmak ile eşittir. Yine aynı şekilde sayıyı 2 sağa kaydırmak sayıyı 4e bölmek demektir.
Barrel Shifter ile kullanacağımız komutlar aşağıda gözükmektedir.
| Operation | Description | Assembler | Cycles |
|---|---|---|---|
| Shift | Logical shift left | LSL Rd, Rn, #<imm> |
1 |
| Logical shift left | LSL Rd, Rn, Rs |
1 | |
| Logical shift right | LSR Rd, Rn, #<imm> |
1 | |
| Logical shift right | LSR Rd, Rn, Rs |
1 | |
| Arithmetic shift right | ASR Rd, Rn, #<imm> |
1 | |
| Arithmetic shift right | ASR Rd, Rn, Rs |
1 |
Burada göreceğiniz üzere komutların kaç cycle alacağı açıklanmıştır ve iki türlü kullanım bulunmaktadır. Bu kullanımlar herhangi bir registerın değeri belirlenen sabit bir sayı kadar kaydırılabilir veya herhangi bir yazmacın belirttiği değer kadar kaydırabilir. Son olarak bir örnek verelim.
- cpsr = nzcvqiFt_USER | r0 = 0×00000000 | r1 = 0×80000004
- MOVS r0, r1, LSL #1
- cpsr = nzCvqiFt_USE | r0 = 0×00000008 | r1 = 0×80000004
Yukarıda örneğimizde ilk önce cpsr bitlerimizin bilgi durumu gösterilmiştir. daha sonra r0 vr r1 yazmaçlarının ilk değerleri belirlenmiştir. Burada MOVS komutu görülmektedir. Bu komut yeni bir komut değildir sadece mov komutuna ekstra özellik kazandırmaktadır. Buradaki S harfi cpsr yazmacının değerini güncelleme demektir. MOVS komutu işletildiğinde görüldüğü gibi r1 yazmacı bir bit sola kaydırılmış ve sonuç r0 yazmacına yazılmıştır ve cpsr yazmacı da C büyük harfle gösterilmiştir yani elde olmuştur.
Bu örneğimizle birlikte bu yazımızın sonuna geldik arkadaşlar, diğer kaydırma operasyonlarını siz evinizde deneyebilirsiniz. Temel olarak mantık aynı olmakla birlikte kaydırmanın niteliği (sola,sağa vs.) değişmektedir. Bir sonraki yazımızda bir aksilik olmazsa ARM’da aritmetik operasyonları nasıl yapabileceğimizden bahsetmeyi düşünüyorum. Herkese iyi çalışmalar.


