Murat ERDEM - Personal Research Blog




Assembly Programing - 0x03: Temel Komutlar

August 26, 2020

Assembly programlamada bazı temel komutlara bu yazımızda göz atacak ve komutların nasıl çalıştığını emu8086 üzerinde test edeceğiz.

Değişken tanımlama

Assembly programlamada değişken tanımlama aşağıdaki şekillerde yapılabilir.


DB Her karakteri 8 bitlik alana yazar
DW Her karakteri 16 bitlik alana yazar
DD Her karakteri 32 bitlik alana yazar

Bu tanımlamalar DS içerisinde yapılır aşağıda bir örnek gösterilmiştir.

       
    
        .data

        bir db 1h
        iki dw 2h
        uc dd 3h 
        dort db 4h
    

Bu tanımlamayı yaptıktan sonra emulatörü çalıştırıp .startup ta yapılan DS tanımlaması atladıktan sonra memory üzerinde DS registerindeki adrese gidersek aşağıdaki gibi bir görüntü elde ederiz.

Yukarıdaki resme dikkatli bakacak olursak DS tanımlaması yapıldıktan sonra memoryde DS registerinin içerisindeki adrese gidersek burada bizim tanımlamalarımızın arka arkaya sıralandığını görürüz.

Burada ilk tanımlamamız bir 0712:0000 adresine yazılmış 8 bitlik bir alana yazılmış. İkinci tanımlamamız olan iki hemen arkasına yazılmış ancak 16 bitlik bir alana yazılmaya çalışıldığını görebiliriz. Kendisi 8 bit ile ifade edilebildiği için hemen sonrasına 8 bitlik bir alan sıfırlar ile doldurulmuş.Aynı şekilde uc tanımlaması da 32 bitlik bir alana yazılamaya çalışılmış.

Köşeli Parantezler [..]

Biz bir adresi registere yazdıktan sonra registerdeki adreste bulunan bir veriye ulaşmak için registerde tutulan değerin bir adres olduğunu belirmemiz gerekir aksi halde registerin içerisindeki adres değeri ile işlem yapacaktır. Bu belirme için köşeli parantez kullanılır.


eax eax registerinin içindeki değeri ile işlem yapar
[eax] eax registerinin içinde bir adres olduğunu bilir ve bu adrese gider oradaki veri üzerinden işlem yapar.

PTR Komutları

Biz bellek üzerinden değer okuduğumuzda kaç bitlik bir değer okuyacağımızı ayarlamak için bu komutlardan faydalanırız.


byte ptr 8 bit boyutunda veri okur
word ptr 16 bit boyutunda veri okur
dword ptr 32 bit boyutunda veri okur

       
    
        #isim = "muraterdem"
        mov ax,word ptr isim
        mov bl, isim
    

Yukarıdaki kod çalıştırıldığında ax registerine “mu” harflerini hex karşılıklarını, bl registerine “m” harfinin hex karşılığını yazacaktır.

DUP(..) ve Soru İşareti (?)

       
    
        .data

        tekrar db 5 dup("m")
        rezerve db ?
    

Örnek olarak DS içerisinde bu şekilde bir tanımlama yaparsak m harfinden 5 adet arka arkaya yazacaktır. Sonuna ise 8 bitlik içerisinde null değer olan bir alan ayıracaktır.

MOV

MOV komutu registerden registere, Bellekten registere yada registerden belleğe veri kopyalama işlemlerinde kullanılır kullanımı aşağıdaki gibidir.

       
    
        mov ax,bx
        mov ax,[bx]
        mov [bx],ax
    

LEA

LEA komutu bir değişkeninin adresini almak için kullanılır, LEA komutu yerine mov komutu ile offset komutu birlikte kullanılabilir. Aşağıdaki iki komutta var_1 değişkeninin adresini ax registerine atar.

       
    
        LEA ax,var_1
        MOV ax, offset var_1
    

ADD

CF te bulunan değeri dikkate almadan toplama işlemi yapar.

       
    
        ADD ax,5
        ADD ax,1234h
    

ADC

CF de bulunan değer, dikkate alarak toplama işlemi yapar.

       
    
        ADC ax, 5h
    

SUB

CF de bulunan değeri dikkate almadan çıkarma işlemi yapar.

       
    
        SUB  ax,5h
    

SBB

CF de bulunan değeri dikkate alarak çıkarma işlemi yapar.

       
    
        SBB ax,5h
    

MUL

işaretsiz sayılar için çarpma işlemi yapar. Bu komutun kullanımı biraz farklıdır, öncelikle çarpanlardan birisini ax registerine atarız diğerini diğer registerlerden birini atarız örnek olarak bx’e. Daha sonra mul komutunu aşağıdaki gibi kullanabiliriz. Bu komut çalıştığında dx:ax tek bir register gibi kullanılarak çıkan sonuç buraya yazılır.

       
    
        mov ax,2
        mov bx,5
        mul bx
        #ax = a
    

IMUL

İşaretli sayılarda çarpma işlemi yapar. mul komutundan çok farklı değildir.

       
    
        mov ax,-2
        mov bx, 5
        imul bx
        #ax = FFF6
    

DIV

İşaretsiz sayılarda bölme işlemi yapar. Kullanımı ve değerlerin yazıldığı registerler aşağıdaki gibidir.


Komut Bölünen Değer Bölen Değer Bölüm Kalan
div cl ax bayt (8bit) al ah
div cl dx,ax word (16 bit) ax dx
div ebx edx:eax double word (32 bit) eax edx

IDIV

İşaretli sayılarda bölme işlemi yapar. div komutu gibi çalışır.

INC

Verilen operandın değerini bir arttırır.

       
    
        inc ax
    

DEC

Verilen operandın değerini bir azaltır.

       
    
        dec ax
    

AND

Mantıksal olarak ve işlemi yapar.

       
    
        and al,0fh
    

OR

Mantıksal olarak or işlemi yapar.

       
    
        or al,ofh
    

XOR

Mantıksal olarak xor işlemi yapar.

       
    
        xor ax, 33h
    

NOT

Mantıksal olarak değil işlemi yapar.

       
    
        not ax
        not [ax]
    

TEST

Mantıksal olarak and işlemi yapar. and işlemi ile arasındaki fark, and işlemi operand olarak verilen registerin içeriğini değiştirirken test işlemi sadece flagları set eder registerin içeriğine dokunmaz.

SHR

İkilik tabanda bitleri belirtilen değer kadar msb bitinden lsb bitine doğru kaydırır her kaydırmada msb bitine 0 değeri lsb bitinde bulunan değeri ise cf içerisine atar. Burada n kaydırmanın 2^n değerine sayıyı bölmek anlamına geldiğine dikkat etmek gerekir.

       
    
        mov al,11111111b
        shr al,5
    

SHL

SHR ile aynı işlemi yapar tek farkı yönü lsb bitinden msb bitine doğrudur.

SAR

Bu komut ikilik tabanda bitleri msb bitinden lsb bitine doğru kaydırır kaydırma sırasında msb bitinin değeri sabit kalarak, lsb biti cf değerine atanır.

       
    
        mov al,01101010b
        sar al,5
    

SAL

SAR ile aynı işlemi yapar farkı lsb bitini sabit tutarak, lsb bitinden msb bitine doğru kaydırma yapar msb değerindeki biti cf değerine atar.

       
    
        mov al,01101010b
        sal al,5
    

ROR

Bu komut msb bitinden lsb bitine doğru kaydırma yapar, lsb bitindeki veriyi hem cf hemde msb bitine aktarır bu şekilde sayılar kaybolmaz.

       
    
        mov al,01101010b
        ror al,5
    

ROL

ROR komutu ile aynı işlemi yapar. Farkı ise lsb den msb ye doğru kaydırma yapar.

       
    
        mov al,01101010b
        ror al,5
    

RCR

Bu komutu ror gibi çalışır ancak farkı cf registerini de sistemin bir parçası gibi görüp 9. bitmiş gibi kaydırma yapar. msb den lsb bitine doğru kaydırma yapar. LSB bitindeki değeri cf registerine, cf değerini msb bitine yazar.

       
    
        mov al,01101010b
        rcr al,5
    

RCL

RCR komutunun tershalidir. msb bitini cf’e cf değerini lsb bitine yazar.

       
    
        mov al,01101010b
        rcl al,5
    

HLT

Program çalışırken bu komut işlenirse program beklemeye alınır.

       
    
        hlt