Mega Code Archive

 
Categories / Delphi / Strings
 

Delphi ile assembly dersleri 2

..::[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