Strings Delphi

..::[Muharrem YILDIZ]::.. Paylaşmayı bilenlere hediyem olsun...
Ennn kolay programlama dili "Assembly" öğrenmeye devam ediyoruz...
İçindekiler:
Aritmetiksel İşlem Komutları
Mantıksal İşlem Komutları
Kaydırma (Shift) Komutları

Tüm örnekler Celeron 2.4 işlemci, Windows XP işletim sisteminde ve Delphi 5 Enterprise sürümünde yazılarak
denenmiştir.
Assembly hakkında yanlış bilinen bir bilgi:
Bazı kaynaklarda assembly dilinin taşınamaz olduğu gibi bir bilgi var.
Assembly dili de birçok donanım üzerinde sorunsuzca çalışır. Ancak şuna dikkat
etmek gerekir. Eğer yazdığınız programda MMX komut setine ait komutlar kullandıysanız
ve yazdığınız programı mmx komut seti olmayan başka bir işlemcide çalıştırmaya çalışırsanız
tabiki çalışmaz. Bu diğer komut setleri için de geçerli. Örneğin SSE2 komut setindeki
komutları destekleyen bir işlemcide, bu komutları kullanarak bir program yazdınız
ve programı sse2 desteklemeyen eski bir işlemcide çalıştırmak istiyorsunuz...olmaaaz..
Eski işlemciler yeni komut setlerini tanıyamaz; fakat yeni işlemciler önceki komut
setlerini tanıyabilir(Genellikle).

Aritmetiksel işlem komutları: Dört işlem komutları (ADD,SUB,MUL,DIV),
Düzenleyici komutlar(AAA,AAS,AAM,AAD,DAA,DAS) ve Ek aritmetiksel komutlar
(CMP,INC,DEC,...)olamk üzere 3 grupta incelenebilir.

Şimdi aritmetiksel işlem komutlarıyla başlayalım...

*******TOPLAMA İŞLEMİ (ADD KOMUTU)********
ADD komutu toplama işlemi için kullanılır.
Yazılımı: Add operand1(Alıcı), operand2(Gönderici) ->Operand2'nin değerini operand1'e ekler
Sonuçta bulunan değer sol taraftaki operandın içine yazılır.
Dikkat!!!: İki oprerandla kullanılan Assembly komutlarının neredeyse tamamında
işlem sonucu soldaki operanda aktarılır.!!!!!!!!! (Öğrenmek için kısa yol)
Dikkat edilmesi gereken başka bir nokta: İki operandın uzunluklarının eşit olması
gerekir. Örneğin operandlardan birisi 32(eax,ebx,...) bitlikse diğeri de 32 bitlik olmalı
Alıcı alan operandı olarak bellek bölgesi, gönderici alan operandı olarak bir sabit değer
seçilmişse, uzunluğun bir uzunluk bildirisi ile (BYTE PRT veya WORD PTR) belirtilmesi
gerekir.
Örnekler: Add Ax,Bx ->Bx'in değerini Ax'E ekle(16 bitlikler)
Add Al,FF ->Al kaydedicisine FF değerini ekle(8 bit)
Add Byte Ptr [100], 80 -> 80 sayısını 100 adresindeki 8 bitlik veriye ekle
Add Ax,[100] -> 100 adresindeki 16 bitlik veriyi ax kaydedicisine ekle
Dikkat ettiyseniz ax'e bellek bölgesindeki bilgiyi eklerken Word Prt kullanmadık
Bunu kendisi kullandığımız kaydediciden anlıyor.(Hani aynı uzunlukta operandlar kullanılıyordu yaaa)
Örnek program: Girilen iki sayıyı toplayıp sonucu görüntüleyen program
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;
SON******************ADD KOMUTU*****************************SON
******* Çıkarma İşlemi (SUB KOMUTU) ***************************
Sub komutu operand2'yi operand1'den çıkarır ve sonucu soldaki operanda (operand1)
aktarır.(Neden iki operandlı komutlarda bir genelleme yaptığım anlaşıldı galiba..)
Yazılımı: SUB Operand1,Operand2
Örnek: SUB Ax,Bx -> Bx'in değeri Ax'ten çıkarılıyor ve sonuç Ax'e aktarılıyor
Sub eax,ebx ->Aynı işlem(sadece kaydediciler 32 bitlik)
Örnek Program:
procedure TForm1.Button1Click(Sender: TObject);
var
sayi1,sayi2:integer;
begin
//Çıkarma işlemi yapılacak
sayi1:=strtoint(edit1.text);
sayi2:=strtoint(edit2.text);
asm
mov eax,sayi1 //sayi1 değişkeninin değeri eax kaydedicisine aktarılıyor
mov ebx,sayi2 //sayi2 değişkeninin değeri ebx kaydedicisine aktarılıyor
sub eax,ebx {eax kaydedicisinin değerinden ebx kaydedicisinin içindeki değerden
çıkarılıyor. çıkarma işleminin sonucu yine eax kaydedicisine
aktarılıyor}
mov sayi1,eax //eax kaydedicisinin değeri sayi1 değişkenine geri aktarılıyor
end;
Showmessage('Çıkarma sonucu: '+inttostr(sayi1));
end;
SON************ÇIKARMA İŞLEMİ ******************SON
************ÇARPMA İŞLEMİ (MUL Komutu) ************************
Mul komutu çarpma işlemi için kullanılır. Yalnız kullanımı biraz farklıdır.
İki operandla kullanılır; fakat iki operand yan yana yazılmaz!!!
Bilirsinizki çarpma işleminde bir çarpan, birde çarpılan vardır :)
Çarpılan değeri akümülatöre (Akümülatör, 32 bitlik için eax, 16 bitlik için ax)
çarpan değerse Mul komutunun yanına yazılır. Görüldüğü gibi Mul komutu Akümülatörü
gizlice kullanır.Örnek:
Mov ax,carpilan ->carpilan değişkeninin değeri ax'e aktarılıyor
Mov bx,carpan ->carpan " " "
Mul bx -> Ax ve Bx içindeki değer çarpılıyor.Sonuç Ax'in içinde(Akümülatör)!!!
Mov sonuc,ax -> İşlem sonucu sonuc adında bir değişkene aktarılıyor...
Örnek program:
procedure TForm1.Button3Click(Sender: TObject);
var
sayi1,sayi2:integer;
begin
//Çarpma işlemi yapılacak
sayi1:=strtoint(edit1.text);
sayi2:=strtoint(edit2.text);
{sayi1 ve sayi2 değişkenlerinin değerleri çarpılıyor ve sonuç yine
sayi1 değişkenine aktarılıyor}
asm
mov eax,sayi1 //sayi1 değişkeninin değeri eax kaydedicisine aktarılıyor
mov ebx,sayi2 //sayi2 değişkeninin değeri ebx kaydedicisine aktarılıyor
mul ebx {ebx kaydedicisinin değeriyle eax kaydedicilirinin değerleri
çarpılıyor ve sonuç yine eax kaydedicisine aktarılıyor}
mov sayi1,eax // eax kaydedicisinin değeri sayi1 değişkenine aktarılıyor
end;
Showmessage('Çarpma işleminin sonucu: '+inttostr(sayi1));
end;
SON ***** ÇARPMA İŞLEMİ ************SON
*******BÖLME İŞLEMİ (DIV Komutu) **********
Bu komutun kullanımı Mul (Çarpma) komutuna benziyor. Fakat birazcık karışık gelebilir.
Kullanımı: DIV bölen
Bölünen değer Ax'te diyeceksiniz ve belki yanılacaksınız....:)
Şimdi sıkı durun...
Bölen değer operandı bir byte uzunluğunda ise (Al,Bl,Ah,Bh,....), bölünen değer
bir word(16bit) uzunluğunda olup ax kaydedicisindedir. Bölen değer bir word uzunluğunda ise
bölünen değer iki word uzunluğundadır ve ax ve dx kaydedicilerindedir(Bir kısmı ax içinde bir kısmı dx içinde).
Böyle bir durumda bölünen değerin yüksek seviyeli kısmı dx, alçak seviyeli kısmı ise
ax kaydedicisinde olduğu kabul edilir.
Örnek program:
procedure TForm1.Button4Click(Sender: TObject);
var
sayi1:word;
sayi2:byte;
begin
//Bölme işlemi yapılacak
sayi1:=strtoint(edit1.text);
sayi2:=strtoint(edit2.text);
asm
mov ax, sayi1 {Word (16 bit) uzunluğundaki bilgi 8 bitlik(bl) bilgiye bölünecek }
mov bl, sayi2
div bl
sub ah,ah//Ax kaydedicisi ah ve al kaydedicilerinden oluştuğu için
// ah kaydedicisinin içi boşaltılıyor. Böylece sonucu ah'nin içindeki değer etkilemiyecek
// Bir sayı kendinden çıkarılırsa sonuç......
mov sayi1,ax
end;
Showmessage('Bölme işleminin sonucu: '+inttostr(sayi1));
end;
SON*******BÖLME İŞLEMİ *********SON
Bu komutların dışında ondalıklı sayılarda çarpma ve bölme işlemi yapmak için
IMUL ve IDIV komutları vardır. Kullanımları MUL ve DIV komutlarıyla benzerdir.
***********EK ARİTMETİKSEL KOMUTLAR *****************
***INC(Artım) ve DEC(Azaltım) komutları***
Yazılımları: INC operand ->Operandın değerini 1 arttırır.
DEC operand ->Operandın değerini 1 azaltır.
Aynı işlemleri add ve sub komutlarıyla da yapabilirsiniz; fakat inc ve dec komutları
bu işlemi daha hızlı gerçekleştirirler.
Örnek: Inc Ax ->Ax'in değeri 1 arttı
Dec eax -> eax'in değeri 1 azaldı
*** CMP Komutu ***
Bu komut genellikle karşılaştırma(kıyaslama) işlemlerinden önce kullanılır.
CMP komutu, tamamen SUB gibi çalışarak, alıcı alan operandının (Oprnd1)
değerinden gönderici(Oprnd2) alan operandının değerini çıkartır. Fakat
Oprnd1'in değeri değişmez, bu işlemden sadece bayrak kaydedicisindeki bayraklar
etkilenir.
CMP komutundan hemen sonra kullanılan koşullu dallanma komutları veya koşullu döngü
komutları, kıyaslama operasyonunun bayraklar(flaglar) üzerindeki etkisini kontrol
ederek icra akışının seçilen bir komuta yönlendirilmesini sağlar.
Bu komutla ilgili örnek dallanma komutlarıyla birlikte verilecektir.
Yazılımı: CMP Operand1, Operand2
CMP ax,bx
CMP eax,ebx //İşlemden eax etkilenmez. Sadece bayraklar etkileniyor.
Örneğin bu işlemden sonra(CMP eax,ebx) ZF(Zero-Sıfır bayrağı) değeri 1 ise
iki değer birbirine eşittir. ZF=0 ise iki değer farklıdır.
Elde bayrağı(CF-Carry Flag) 1 ise ikinci değer (ebx) birinci değerden büyüktür....

SON******* EK ARİTMETİKSEL KOMUTLAR ******SON