ASSEMBLY ÖĞRENİYORUZ :) Muharrem YILDIZ
ENNN KOLAY PROGRAMLAMA DİLİ :)) [Tabiiki delphiden sonra]
Aşağıdaki örnek programlar Delphi 5 versiyonuyla WinXP işletim sisteminde denenmiştir.
***********Assembly programlarının genel yapısı********
Assembly komutları genel olarak 4 kısımdan oluşur
1-)etiket alanı 2-)komut alanı 3-)Operand alanı 4-)Açıklama alanı
Etiket programı istediğimiz yere yönlendirmek için kullanılır
komut istediğimiz işlemi yapar
işlem operand alanı üzerinde yapılır.(Şu alanlar üzerinde şu işlemi[komut] yap diyoruz)
programla ilgili açıklamayarı ; işaretinden sonra yapabiliriz;fakat delphide açıklama satırları
farklı( {}, //
veya (* *) işaretleriyle açıklama ekleyebiliyoruz)
Örnek: toplama: -->etiket
add ax,bx ;hebele hübele -->add(komut) ax,bx (operandlar) ; işaretinden
sonrası açıklama
***********KOMUTLAR****************
Mov(taşıma) ve Add(ekleme[toplama]) komutlarına örnek
yazımı: mov alıcı,değer
Örnek: mov ax,1 {ax kaydedicisine 1 değeri aktarılıyor}
add alıcı,değer
Örnek: add ax,bx {bx kaydedicisinin değeri ax kaydedisinin değerine ekleniyor}
Kaydedicileri birer değişken olarak düşünebilirsiniz. Farkı cpu'nun içinde olmaları.
Bu nedenle çok hızlı bir şekilde işlem yapılabiliyor.Aktaracağınız değere göre
kaydedici seçmelisiniz. Örneğin 32 bitlik veri üzerinde işlem yapacaksanız(integer veya longint)
32 bitlik değişken kullanmalısınız. 16 bitlik veri(smallint)........16 bitlik kaydedici
8 bitlik veri(byte veya shortint).....8 bitlik kaydedici.
Delphiyle kullanabileceğiniz kaydediciler:
32 bitlikler: eax,ebx,ecx,edx,esp,ebp,esi,edi
16 bitlikler: ax,bx,cx,dx,sp,bp,si,di,cs,ds,ss,es
8 bitlikler: al,bl,cl,dl,ah,bh,ch,dh
DİKKAT!!bazı kaydecilerin özel işlevleri vardır ve değerlerinin değişmemesi gerekir!!
Bu durumda kaydedicinin değerinin önce saklanması, üzerinde işlem yapıldıktan sonra eski değerine tekrar döndürülmesi
gerekir. Push komutu kaydedicinin değerini saklar. Üzerinde işlem yaptıktan sonra
pop komutuyla ilk değerine geri döndürebilirsiniz. Örnek:
cx kaydedicisinin ilk değeri 5 olsun
push cx {cx in değerini sakla (5)}
mov cx,1 {1 sayısını cx'e taşı}
..... {işlemler....}
pop cx {cx in değerini ilk haline getir (5)}
**********Mov ve Add komutlarına örnek**************
Formunuza 2 adet edit(metin kutusu) ekleyin
[] köşeli parantez içinde bişey görürseniz bunun adresi gösterdiğini unutmayın
Ör: [100] -->100 nolu adres, [eax] -->eax içindeki bulunan adresteki bilgi
function topla(var x,y:integer):integer;stdcall;
begin
asm
mov eax,x { x değişkeninin adresi eax kaydedicisine aktarılıyor}
mov eax, [eax] { eax kaydedicisinde bulunan adresin içindeki bilgi yine eax kaydedicisine aktarılıyor. DİKKAT! [] köşeli parantez içindeki kaydedicinin adresini belirtir. Ör: [eax]-->eax'in adresi }
mov edx,y {y değişkeninin adresi edx kaydedicisine aktarılıyor}
add eax,[edx] {edx kaydedicisinde bulunan adresin içindeki bilgi eax kaydedicisinin içindeki bilgiye(sayıya) ekleniyor(toplama işlemi) }
mov @result,eax {eax kaydedicisinin içindeki bilgi topla fonksiyonuna aktarılıyor}
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
a,b,c:integer; // üç adet tamsayı tanımlanıyor
begin
a:=strtoint(edit1.text); //edit1 nesnesine girilen yazı sayıya çevrilerek a değişkenine aktarılıyor
b:=strtoint(edit2.text); //edit2 nesnesine girilen yazı sayıya çevrilerek b değişkenine aktarılıyor
c:=topla(a,b); // girilen sayılar topla fonksiyonuna gönderiliyor ve gelen sonuç c değişkenine aktarılıyor.
showmessage(inttostr(c)); // c tamsayı değişkeninin içindeki bilgi yazıya çevrilip ekrana mesaj olarak yazdırılıyor.
end;
**********Mov ve Add komutlarına örnek**************
**********XCHG komutu(Karşılıklı olarak yer değiştirme komutu)**********
XCHG komutu iki kaydedicinin değerlerinin karşılıklı olarak yer değiştirmesini sağlar
Örnek: eax in ilk değeri 3, ebx in ilk değeri 5 olsun
XCHG eax,ebx deyince
eax in değeri 5, ebx in değeri 3 olarak yer değiştiriyor.
Aşağıdaki program iki değişkenin değerlerini karşılıklı olarak yer değiştirir.
formunuza iki adet edit kutusu ekleyin
procedure TForm1.Button1Click(Sender: TObject);
var
sayi1,sayi2:integer;
begin
sayi1:=strtoint(edit1.text);
sayi2:=strtoint(edit2.text);
{Şimdi assembly yardımıyla iki değişken içindeki bilgi
yer değiştirecek
Dikkat integer(32bit) değişken kullanıldığı için 32 kaydediciler kullanıldı(eax,ebx)}
asm
mov eax,sayi1 //sayi1 değişkeni eax kaydedicisine aktarılıyor
mov ebx,sayi2 //sayi2 değişkeni ebx kaydedisine aktarılıyor
xchg eax,ebx //eax ve ebx kaydedicilerinin içlerindeki değerler yer değiştiriyor
mov sayi1,eax //eax kaydedicisindeki değer sayi1 değişkenine geri aktarılıyor
mov sayi2,ebx //ebx kaydedicisindeki değer sayi2 değişkenine aktarılıyor.
end;
showmessage('Sayi1:='+inttostr(sayi1)+' Sayi2:='+inttostr(sayi2));
{
Eğer xchg komutunu kullanmasaydık kod şu şekilde olacaktı
asm
mov eax,sayi1 //sayi1 değişkeni eax kaydedicisine aktarılıyor
mov ebx,sayi2 //sayi2 değişkeni ebx kaydedisine aktarılıyor
push ecx // ecx kaydedicisinin mevcut değeri saklanıyor(ecx değişimi önemli değil. Olmasa da olur)
mov ecx,eax //eax ecx e aktarılıyor
mov eax,ebx //ebx eax e aktarılıyor
mov ebx,ecx //ecx ebx e aktarılıyor
pop ecx //ecx eski değerine döndürülüyor(en baştaki değerine--ecx kaydedisi değer değişimi önemli değil)
mov sayi1,eax //eax kaydedicisindeki değer sayi1 değişkenine geri aktarılıyor
mov sayi2,ebx //ebx kaydedicisindeki değer sayi2 değişkenine aktarılıyor.
end;
Yukarıdaki push ve pop komutları silinsede program çalışır.
Çünkü ecx'in değişimi bir soruna neden olmaz.
Değeri değişmemesi gereken bir kaydedici değil
}
end;
**********XCHG komutu(Karşılıklı olarak yer değiştirme komutu)**********
****************XLAT Komutu(Bir dizi içinde istenilen elemanı bulmak)********
XLAT komutu bir dizinin içinde istenilen elemanı bulmak için kullanılır
XLAT komutu bazı kaydedicileri gizli olarak kullanır.ebx kaydedicisine
içinde istediğimiz elemanını bulacağımız değişkenin offset adresini taşıyıp,
al kaydedicisine hangi elemanını bulmak istediğimizi iletiyoruz...
XLAT komutunu veriyoruz. Elemanı buluyor ve elemanın ascii konudu yine al kaydedicisine veriyor.
Böylece istediğimiz elemanı bulmuş oluyoruz.
Al kaydedicisi 8 bit olduğu için dizimiz en fazla 256 karakter uzunluğunda olabilir.
iki adet edit kutusunu formunuza ekleyin
procedure TForm1.Button1Click(Sender: TObject);
var
sirano,sonuc:byte;
mesaj:shortstring;
begin
mesaj:=edit1.text;
sirano:=strtoint(edit2.text);
asm
//mov bx,offset mesaj {32 için bu satır çalışmıyor(lea yerine)}
lea ebx,mesaj {mesaj değişkeninin offset adresi ebx e aktarılıyor}
mov al,sirano {sirano al kaydedicisine aktarılıyor}
xlat {belirtilen adreste,belirtilen sıradaki veri al kaydedicisine aktarılıyor}
mov sonuc,al {al kaydedicisindeki veri sonuc değişkenine aktarılıyor}
end;
showmessage(chr(sonuc));
end;
****************XLAT Komutu(Bir dizi içinde istenilen elemanı bulmak)********
Umarım yararlı olur.