Hakkında Künye

Assembler Çalışma Mantığı

Öncelikle nedir bu assembler?

Assembler Türkçe ismiyle çevirici, Assebmly ile yazılan programları makina diline(ya da obje diline) çeviren bir yazılımdır.

Bildiğimiz üzere makina diline en yakın olan dil Assembly dilidir. Makina diline bu kadar yaklaşmışken neden bi tık daha ilerisine bakıp Assembly’nin makina diline nasıl çevrildiğini öğrenmeyelim ki?

Yine bildiğimiz üzere assembly dili bilgisayarın mimarisine göre şekil alır ve bu sebeple Assembler'lar ve dolayısıyla ortaya çıkardıkları binary dosyalar da çeşitlilik gösterir. Bu yazıda kullanımı yaygın olan Mips Assembly dilinin çalışma mantığını ve Mips Assemblysinin obje diline çevrilme hikayesine bakacağız hep beraber.

Mips mimarisine kısaca bir göz atmak gerekirse:

  • Bütün komutlar 32 bitliktir.
  • Bir byte 8 bit, word(kelime) 4 byte, yarı kelime ise 2 byte’tır.
  • Bir char değişkeni 1 byte, bir integer değişkeni ise 4 byte yer kaplar.
  • 32 register vardır. Registerlar isimleriyle ($t1,$sp gibi) ya da karşılık gelen sayılarla ifade edilirler ($1, $21 gibi).
  • Mips mimarisi RISC (Reduced Instruction Set Computer) mimarisinin ilk örneklerindendir (RISC ve CISC hakkında daha ayrıntılı bilgiye verdiğim linklerden ulaşabilirsiniz).

Komut Formatları:

Mips mimarisinde 3 farklı komut vardır:

  • Register tipi komutlar
  • Immediate tipi komutlar
  • Jump tipi komutları

Register tipi komutlar:

Registerlar arasında işlem yapılmasını sağlayan komutlardır.Örnek olarak:

    add     $t0,$t1,$t2

    mult    $t0,$t2

    mfhi    $t1

    jr  $ra

Immediate tipi komutlar:

Sayılarla işlem yapılırken, branch operasyonlarında ve load/store operasyonlarında kullanılan komutlardır. Örnek olarak:

    ori     $t1,$t2,83

    bne     $t1,$t3,foo

    lw  $t1,101($s2)

    sw      $t3,110($sp)

Jump tipi komutlar:

Fonksiyon çağırmada kullanılan komutlardır:

    j       label

    jal     label

Bir komutu assemble etmek için sırasıyla şu adımlar uygulanır:

  • Komutun R,I ve J formatlarından hangisi olduğu belirlenir.
  • Bütün parçaların değeri hesaplanır.
  • Bu değerler binary’ye çevrilir.
  • Binary değerleri hexadecimal’e çevrilir.

R-tipi komutların assemble edilmesi :

İlk 6 bit her zaman 0 olmakla birlikte rs, rt, rd (her biri 5 bit) sırayla ikinci, üçüncü ve birinci registerları temsil eder. Shamt(5 bit) ise yapılacak olan shift(kaydırma) sayısıdır ki o kısım da bizim için 0'dır. Funct kısmı ise tahmin ettiğiniz üzere uygulanacak olan fonksiyonu (mnemonic) temsil eder. Örnek vermek gerekirse:

    add $t1, $t2, $t3

    rs = 10

    rt = 11

    rd = 9

    funct = 32  (add fonksiyonun değeri. Diğer fonksiyonlar için yazının sonundaki linke bakabilirsiniz).

    shamt = 0  . (Shift yapmadığımız için)

Sonuçta tablomuz:

    000000   10   11   9   0   32

Binary karşılığı:

000000   01010   01011   01001   00000   100000

-

0000     0001     0100     1011     0100     1000     0010     0000

Hexadecimal karşılığı:

    0x014B4820

I-tipi komutların assemble edilmesi:

    op(6 bit)   rs(5 bit)   rt(5 bit)   adres/değer(16 bit)

Op(6 bit) yapılacak olan operasyondur. rs argüman olarak verilen ilk register, rt ikinci argüman ya da sonucun tutulduğu registerdır. Adres/değer kısmı ise verilen değer ya da adresin kaydedildiği kısımdır.

Örnek olarak:

    addi $t4, $t5, 67

    op = 8      (addi operasyonun değeri)

    rs = 13         ($t5'in değeri. İlk argüman olduğu için $t5'i aldık).

    rt  = 12    ($t4'ün değeri)

    değer = 67

-

    8   13   12   67

Binary karşılığı:

    001000   01101   01100   0000000001000011

-

0010 0001 1010 1100 0000 0000 0100 0101

Hexadecimal karşılığı:

    0x21AC0043

J-Tipi komutların assemble edilmesi:

    operasyon   adres

J-tipi komutlar j ve jr’dir. Operasyon kısmına her zamanki gibi operasyona karşılık gelen sayı yazılır. Fakat adres kısmı J-tipi komutlarda biraz daha farklıdır. Adres kısmını doldurmadan önce yaptığımız işlemleri bir örnek üzerinde anlatmak gerekirse:

Adresimiz hexadecimal olarak 0x400004B olsun.

  • İlk önce adresin ilk basamağını sileriz: 0x00004B = 04B
  • Binary’ye çeviririz: 0100 1011
  • Son iki bitini atarız: 010010

Örnek olarak fonksiyonun adresi az önce hesapladığımız adres olsun:

    j    fonksiyon

-

    2    010010

-

    000010   00   0000   0000   0000   0000   0001   0010

-

    0000   1000   0000   0000   0000   0000   0001   0010

Hexadecimal değeri ise:

    0x08000012

Anlatacaklarım bu kadar. Okuduğunuz için teşekkür ederim.

Kaynaklar:

CISC ve RISC için:

Operasyon kodları için:

Baran Barış Kıvılcım
- 6 -