ASSEMBLY KOMUTLARI :
Mantık Komutları: Arkadaşlar Mantıksal işlemlerde VE, VEYA, DEĞİL,
VEYA DEĞİL gibi mantık karşılaştırmaları vardır. Bunlar assembly de
AND, OR, XOR, NOT komutlarıyla işlevlerini gerçekleştirirler. Buradaki
amaç en iyi seçenekleri bulmak ve istenildiği şekilde gruplama
yapabilmektir. Mantıksal yani diğer adıyla Lojik işlemler bit’lerin
temizlenmesini (0’lanmasını), 1’lenmesini veya tersinin alınmasını
sağlar. Bütün lojik işlemler bayrak bit’lerini etkiler.Şimdi bu
komutları görelim.
AND komutu : AND komutu işlem sırasında “hedef” ve “kaynak”
bölgesindeki değerleri mantıksal VE işlemine tabi tutar ve işlemin
sonuncunu “hedef” alana kaydeder. Yapı olarak AND (VE) mantığı 1 ve
0’lar ile ifade edilirse aşağıda ki şekilde açıklayabiliriz;
1 ve 1 = 1
1 ve 0 = 0
0 ve 1 = 0
0 ve 0 = 0
sonuçlarını üretir.Yukarıda da görüldüğü gibi arkadaşlar her iki
değerde 1 ise sonuç 1 oluyor.Aksi durumlarda sonuç hep 0 olur. Bu
komutu assembly programcıları genelde maskeleme işlerinde kullanırlar
Aşağıdaki örnek açıklayıcı olacak;
Mov ah,09h - ah ye 9 değerini yükledik
Mov al,05h - al ye 5 değerini yükledik
And ah,al - And işlemine tabii tutup sonucu AH de saklıyoruz.
Yukarıda ki işlem şu şekilde işleyecektir.
Ah = 00001001
Al = 00000101
And =---------------
00000001 = sonuç 1 olacak ve Ah ye yazılacaktır.Bu şekilde maskeleme
yaparak 4 bite dokunmadan diğer bitleri sıfırlamakta denilebilir.
TEST Komutu : TEST komutu tamamen AND komutu gibi çalışır. Tek
fark elde edilen sonucun hedef alana aktarılmaması onun yerine değişen
flag bitlerine göre programın akışının kontrol edilmesidir.
OR Komutu : Bu komut da arkadaşlar mantıksal VEYA işlemine tabii
tutar.Yukarıda ki AND işlemi gibi bitlerle işleme sokulur.OR işleminde
her iki değerden birinin 1 olması durumunda sonuç yine 1 olur.Sadece
her iki değerde 0 olursa sonuç 0 olur.Aşağıdaki tablo açıklar nitelikte.
1 veya 1 = 1
1 veya 0 = 1
0 veya 1 = 1
0 veya 0 = 0
XOR Komutu : XOR komutunu arkadaşlar şu şekilde açıklayabiliriz,
iki operand aynı ise 0, farklıysa 1 değerini veren bir işlemdir.Yada
"aynılarda 0 farklılarda 1" sonucunu veren mantıksal ifadedir
diyebiliriz. Özellikle şifreleme işlemlerinde tercih edilir ayrıca
program içerisinde bir registerde ki değerleri sıfırlamak içinde
kullanılır.Örneğin XOR EAX,EAX gibi bir kullanımda EAX içerisindeki
değer sıfır olur ,bu kullanım MOV EAX,0 komutuyla aynı işi yapmasına
rağmen XOR komutu daha hızlı ve seri çalışır.. Bir sayıyı kendisiyle
XOR işlemine sokarsak 0 elde ederiz..
1 -- 1 = 0
1 -- 0 = 1
0 -- 1 = 1
0 -- 0 = 0
NOT Komutu : NOT komutu "değil" anlamına gelir. Bunu bitlerin
değili anlamında düşünürsek 1 ise 0 ; 0 ise 1 demek oluyor. Yani
bitleri tam tersine çevirmiş oluyoruz.. NOT komutu diğer mantıksal
komutlardan ayrı olarak flag register üzerine etki etmeyen tek
komuttur. Kullanım şekli ile de diğer komutlardan farklılık gösterir.
Direk “hedef” alan içerisindeki değerin bitleri ters çevrilip yine aynı
alana yazılır.
1 Değil = 0
0 Değil = 1
Döngü Komutları : Evet arkadaşlar her programlama dilinin
vazgeçilmezi olan döngü komutları da assembly ‘de aynı yere
sahiptir.Döngü komutları verilen herhangi bir rutini koşul sağlanıncaya
çalıştırır.Diğer dillerde ki For-next veya while-wend komutları gibi.
Döngü komutları genelde şunlardır: LOOP, LOOPE, LOOPNE, LOOPZ, LOOPNZ.
Bunlar CX (Count Register) yada ECX registerin durumuna göre işlem
yapar..Döngü komutları LOOP ile başlar ve yanına aldığı ayrı bir opkod
oluşur. Aldığı ek işlemi yapma ve devam etme şartıdır. Bu komutlar
daima CX (veya ECX) register ile birlikte çalışır. Şartı ve döngü
uzunluğunu bu sayaç register oluşturur. Daha önce gördüğümüz bayraklar
burada da etkindir. Karşılaştırma ve şartın yerine getirilmesi kontrolu
Z (sıfır bayrak = zero flag) ile kontrol edilir. Döngüyü kaplayan
alanın bir sınırı vardır. Bunun nedeni ise döngü noktasını belirten
değerin 8 bitlik bir sayı olması. Bu kodun +127 byte yukarı ve -128
byte aşağıya kadar ulaşması demektir.
LOOP Komutu : LOOP komutu arkadaşlar o andaki CX (Count Register)
yada ECX sayaç registerinin değeri 0 oluncaya kadar döngüyü işletir.
Şartı sayaç registerin 0 olmasıdır. Yani her döngüde CX içerisindeki
değer bir azaltılır ve CX’in değeri sıfır oluncaya kadar işlem devam
eder.
XOR AX, AX AX degerini sıfırladık
MOV CX,0005 CX 5 degerini atadık
INC AX AX 1 eksilt
LOOP Tekrar INC komutuna dönecek
LOOPE ve LOOPNE Döngüleri : Eşit olması yada olmaması gibi bir
durum kontrol eder. Burada yapılan işlem diğerleri gibidir ve pek bir
fark yoktur.Loop kelimesinin sonundaki ”E” eşit (Equal) ve “NE”
kelimeside (Not Equal) yani eşit değilse anlamındadır.Böyle bir döngü
ile karşılatıgınız zaman ne anlamı oldugunu hemen anlarsınız.Burda CX
deki değer verilen şarta eşit ise veya değil ise döngü ona göre
çalıştırılır.
LOOPZ ve LOOPNZ Döngüleri : Bu döngüler bir işlemin sonucu 0 ise
zero flag bitinin (sıfır bayrak biti) olması durumuna göre çalışır.
Genelde bu döngü komutları daha çok kullanılır ve ikiside sayaçlı bir
döngü işlemi için yeterlidir. LOOPZ komutu (Sonundaki “Z” opkodu Zero
yani sıfır anlamında) CX veya ECX registerin o değerine ulaşıp
ulaşmadığını kontrol eder. Bir bakıma yukarıda bahsettiğim LOOP komutu
gibidir ve tek farkı bayrak kontrolu olmasıdır. LOOPNZ ise 0 değilse
durumunu kontrol eder. Yani sayaç registerin değeri 0 değilse devam
eder.
ATLAMA KOMUTLARI
Namı diğer Dallanma komutları, programın normalde yukarıdan aşağı
doğru giden akışını herhangi bir koşula bağlı olarak yada koşulsuz
olarak başka bir yere yönlendirmek amacı ile kullanılır. Kullanılan bu
dallanma komutları yüksek seviyeli dillerdeki “if” veya “goto”
komutları gibi düşünülebilir.
Assembly dilinde kullanılan dallanma komutları atlama yaptıkları yere
göre FAR veya NEAR özelliği taşır. NEAR özelliği taşıyan komutlar 2-3
bayt yer tutarken FAR özellikli olanlar 5 bayt yer tutmaktadır.
Komutlar arasındaki fark, FAR özelliği taşıyanların farklı segment
içerisindeki noktalara dallanma için kullanılmasıdır. Gerekli olmamakla
beraber dallanmanın türü “FAR PTR” yada “NEAR PTR” ile belirtilebilir.
JMP (Koşulsuz Dallanma) Komutu: JMP komutu belirtilen herhangi bir noktaya koşulsuz olarak dallanma yamak için kullanılır.
jmp hedef şeklinde gösterilebilir.Aşağıda karşılşabileceğiniz atlama
komutalarını ve anlamlarını içeren bir tablo veriyorum.Bu tablo çok
işinize yarayacak.
Hex Kodu: ASM Kodu: Anlamı:
75 yada 0F85 jne jump if not equal
74 yada 0F84 je jump if equal
EB jmp jump directly to
90 nop no operation
77 yada 0F87 ja jump if above
0F86 jna jump if not above
0F83 jae jump if above or equal
0F82 jnae jump if not above or equal
0F82 yada 72 jb jump if below
0F83 yada 73 jnb jump if not below
0F86 yada 76 jbe jump if below or equal
0F87 jnbe jump if not below or equal
0F8F yada 7F jg jump if greater
0F8E jng jump if not greater
0F8D jge jump if greater or equal
0F8C jnge jump if not greater or equal
0F8C jl jump if less
0F8D jnl jump if not less
0F8E jle jump if less or equal
0F8F jnle jump if not less or equal
Şimdide isterseniz bu atlama komutlarının ne işe yaradığını kısaca anlatayım arkadaşlar..
JZ/JE Komutları : JZ/JE (Jump if Zero/Jump if Equal) komutları herhangi
bir işlem sonrasında zero flag’ın değerine göre programın akışını
düzenler. Komutun icrası sırasında zero flag içerisindeki bit değeri 1
ise program JZ komutu ile gösterilen yere atlar aksi taktirde işlemci
JZ komut yokmuş gibi programın akışına devam eder.
JNZ/JNE Komutları : JNZ/JNE (Jump if Not Zero/Jump if Not Equal)
komutları JZ ve JE komutlarının zıttı olarak kullanılır. Herhangi bir
işlem sonrasında zero flag içerisindeki değer sıfır değil ise program
komutun gösterdiği yere dallanarak akışına devam eder.
JB/JC/JNAE Komutları : JB/JC/JNAE (Jump if Below/Jump if Carry/Jump if
Not Above or Equal) komutları carry flag’ın değerine göre dallanma
gerçekleştirirler. Herhangi bir işlem sonrasında carry flag
içerisinde 1 değeri varsa programın akışı JB komutu ile gösterilen yere
gider. Aksi taktirde JB komutu dikkate alınmadan programın normal
akışına devam edilir.
JBE/JNA Komutları : JBE/JNA (Jump if Below or Equal/Jump if Not Above)
komutlarının icrası sırasında carry ve zero flag’ları kontrol edilir.
Bir işlem sonrasında iki flag’dan birinin 1 olması durumunda JBE komutu
ile gösterilen noktaya dallanma yapılır.
JL/JNGE Komutları :JL/JNGE (Jump if Less than/Jump if Not Greater or
Equal) komutlarının gerçekleşmesi için gerekli koşul carry ve overflow
flag bitlerinin birbirinden farklı değerler taşımasıdır. İki bitin
farklı değerler içermesi durumunda programın akışı JL komutu ile
gösterilen noktaya yönlendirilir.
JS ve JNS Komutları : JS
(Jump if Sign) ve JNS (Jump if No Sign) komutlarının icrası sırasında
sign flag kontrol edilir. Sign flag içerisindeki değerin 1 olması JS için, sıfır olması JNS için gerekli koşuldur. Gerekli koşulun sağlanması durumunda program JS veya JNS komutu ile gösterilen noktadan akışına devam edecektir.
JO ve JNO Komutları : JO (Jump if Overflow) ve JNO (Jump if No
Overflow) komutlarının icrası sırasında overflow flag içerisindeki
değere bakılır. Overflow flag içerisinde 1 JO komutu için ve sıfır
olması JNO komutu için gerekli koşuldur.
KAYDIRMA ve DÖNDÜRME KOMUTLARI
Bit çevirme ve kaydırma komutları pek çok alanda kullanılır.
Grafiksel işlemlerde, çevrim işlemlerinde, sayaçlarda,... Bit kaydırma
kendi arasında kaydırma komutları ve çevirme komutları komutları olarak
ikiye ayrılır. Kaydırma komutlarıda aritmatik ve logical olarak ikiye
ayrılırlar. Bunların arasında işlevsel bir farklılık vardır. Kaydırma
komutları biti sonuç 0 oluncaya kadar sağa yada sola doğru kaydırır.
Kaydırılan bit yokolur ve tersine işlem yapılsa bile geriye dönemez.
Çevirme komutları ise bitleri çevirerek dönüşüm yapar ve bit sayısına
bağlı olarak tekrar eski değerine ulaşır. Çevirme komutlarında hiçbir
bitin değeri kaybolmaz. Daima çevrimiçi olarak kalır. İki komut
grubunda da sağa ve sola kaydırma mevcuttur ve ingilizcedeki left,
right kelimelerinin başharfleri ile belirtilirler. Bu komutlar yardımcı
register ile kullanılarak blok kaydırma veya çevirme işlemlerine tabi
tutulabilirler. Yardımcı register değişmez olarak CL registerdir ve
burada bir sayaç görevini üstlenir. Registerdeki sayının bitini şu
kadar kaydır diye komut verebiliriz. Özellikle aritmatiksel kaydırma
komutları register-register kullanılımı ile kaydırmak işlevine
sahiptirler. Burada kaydırma sayısı registeri 0-31 sayıları olmak
zorunda çünkü şu anda bu komutlar en fazla 32 bitlik registerleri
kullanabiliyor.
Mantıksal kaydırma ve çevirme komutları bildiğimiz matematiksel bölme
ve çarpma işlemlerinin aynısı yaparlar. Sağa doğru yapılırsa çarpma,
sola doğru yapılırsa bölme işleminin aynısını yapmış olurlar.
Mantıksal kaydırma komutları : Örnek olarak elimizde eax registerde
00111000 şeklinde bir sayımız var. Bu sayıyı 1 bitlik kaydırma işlemine
tabi tutuyoruz:
MOV EAX ,00111000
SHL EAX,1
Eax=01110000
Burada shl eax,1 komutu ile eax registerdeki bitleri sola doğru
(shl= sola , shr = sağa) kaydırdık. Örnektede görüldüğü gibi ilk bit 0
oldu ve ilk set olan bit sola doğru kaydı. Sonuçta sayının değeri iki
katına çıkmış oldu. Çünkü basamak atladı.Eğer biz bu işlemi 5 kere daha
yaparsak bütün bitler sola doğru kayacağı ve yerlerin resetleyeceği
için sonuç 0 olacaktır. Yani sayı döngü içinde mutlaka 0 değerine
ulaşacaktır. Buradaki 0 değeri olarak bahsettiğim bitlerin tamamının
sıfırlanması ve sayıyın değerini tamamen kaybetmesi oluyor.
shl eax,1 ; 01110000 <-
shl eax,1 ; 11100000 <-
shl eax,1 ; 11000000 <-
shl eax,1 ; 10000000 <-
shl eax,1 ; 00000000 <-
Eğer sayıya shr işlemine (sağa kaydırma) tabi tutarsak:
shr eax,1 ; 01110000 ->
shr eax,1 ; 00111000 ->
shr eax,1 ; 00011100 ->
shr eax,1 ; 00001110 ->
shr eax,1 ; 00000111 ->
shr eax,1 ; 00000011 ->
shr eax,1 ; 00000001 ->
shr eax,1 ; 00000000 ->
Mantıksal Döndürme komutları:Mantıksal döndürmek komutları aynı
kaydırma komutları gibi bitleri sağa yada sola kaydırır yalnız bitlerin
değeri kaybolmaz her kayan bitin yerine bir önceki bit gelir. Son bit
ilk bir ile yer değiştirir veya ilk bir son bit ile yer değiştirir.
Eğer döndürülecek registerin değeri 0 değilse ve değerini yokedecek
başka bir işlem yapılmıyorsa değeri asla 0 olmaz. Çevrimi bir daire
gibi düşünebiliriz. Aynı dünyanın güneş etrafında dönüşü gibi belli bir
süre sonra bitler tekrar aynı yerlerine gelecektir. Yine kaydırma
komutarı gibi tek tek yada yardımcı register vasıtasıyla birden fazla
kombine çevrim mümkündür.
Ayrıca RCR ve RCL çevirme komutlarıda CL register ile kombine
kullanılır. İşlevleri aynıdır ancak C bayrağı ile birlikte kullanılır.
Bu sayede döndürme işlemini bayrak bazında kontrol altına alabiliriz.
Örneğin döndürülen sayının 0 olması durumda.
mov ax,0111000
mov cl,5
rcl ax,cl