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.
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ış.
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. |
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.
.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 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 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
CF te bulunan değeri dikkate almadan toplama işlemi yapar.
ADD ax,5
ADD ax,1234h
CF de bulunan değer, dikkate alarak toplama işlemi yapar.
ADC ax, 5h
CF de bulunan değeri dikkate almadan çıkarma işlemi yapar.
SUB ax,5h
CF de bulunan değeri dikkate alarak çıkarma işlemi yapar.
SBB ax,5h
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
İşaretli sayılarda çarpma işlemi yapar. mul komutundan çok farklı değildir.
mov ax,-2
mov bx, 5
imul bx
#ax = FFF6
İş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 |
İşaretli sayılarda bölme işlemi yapar. div komutu gibi çalışır.
Verilen operandın değerini bir arttırır.
inc ax
Verilen operandın değerini bir azaltır.
dec ax
Mantıksal olarak ve işlemi yapar.
and al,0fh
Mantıksal olarak or işlemi yapar.
or al,ofh
Mantıksal olarak xor işlemi yapar.
xor ax, 33h
Mantıksal olarak değil işlemi yapar.
not ax
not [ax]
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.
İ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
SHR ile aynı işlemi yapar tek farkı yönü lsb bitinden msb bitine doğrudur.
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
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
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
ROR komutu ile aynı işlemi yapar. Farkı ise lsb den msb ye doğru kaydırma yapar.
mov al,01101010b
ror al,5
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
RCR komutunun tershalidir. msb bitini cf’e cf değerini lsb bitine yazar.
mov al,01101010b
rcl al,5
Program çalışırken bu komut işlenirse program beklemeye alınır.
hlt