|Refleks|-Oyun,Tasarım,Film,Program,Tek link,İndir
Would you like to react to this message? Create an account in a few clicks or log in to continue.

|Refleks|-Oyun,Tasarım,Film,Program,Tek link,İndir


 
AnasayfaLatest imagesAramaKayıt OlGiriş yap

 

 Assembly Nedir?

Aşağa gitmek 
YazarMesaj
FaTaL
Yönetici
Yönetici
FaTaL


Ruh Hali : Assembly Nedir? Manyak10
Başak Mesaj Sayısı : 626
Rep Puanı : 12348
Teşekkür Aldı : 18
Kayıt tarihi : 24/10/09
Nerden Nerden : Kocaeli
İş/Hobiler İş/Hobiler : 3D / Maya / After Efect
Lakap Lakap : Fatal

Assembly Nedir? Empty
MesajKonu: Assembly Nedir?   Assembly Nedir? EmptyCuma Ekim 30, 2009 9:13 am

Assembly aslında öğrenilmesi zor bir dildir. Uzun zaman ve büyük
emek ister. Fakat iyi bir şekilde anlatıldığında hiçte zor değil. Ama
baştan şunu belirteyim: Diğer programlama dillerinde yaptıklarınızı
assembly altında daha çok satır kod yazarak ve daha uzun bir zamanda
elde edebilirsiniz. Buna karşın diğer dillere göre birçok üstünlüğü
bulunmaktadır. Lütfen bu sayfayı sonuna kadar okumaya devam edin.

Bir programlama dili öğrenecek insan öncelikle kolay bir dili öğrenmeli
(Bu genelde Basic’dir.) Bu dil vasıtası ile programlama ve algoritma
geliştirme (problemlere karşın geliştirilen hatasız ve tatmin edici
çözümler diyebiliriz) hakkında bilgi ve deneyim sahibi olmalı. Son
olarak ise diğer dilleri tanımalı ve seçtiği dili öğrenmeli,
uygulamalar geliştirmelidir.

0C85:0100 B402 MOV AH,02
0C85:0102 B203 MOV DL,03
0C85:0104 CD21 INT 21
0C85:0106 CD20 INT 20

Yukarıda ayrıntılı çıktısı alınmış bir kod parçası bulunuyor. (Daha
sonra ne işe yaradığını anlatacağım) Gri renkteki bölümler bellek
lokasyonlarıdır. Yani ilgili kodların şu anda hangi bellek adresinde
bulunduğunu gösteriyor bize. Kırmızı renkteki yazılar assembly
kodlarıdır. Koyu yeşil kısımlar ise bu assembly kodlarının makina
diline çevrilmiş halidir. Bizi ilgilendiren kırmızı bölümler olacak.
Biliyorum o yazılardan hiçbir şey anlamadınız, bu çok normal...

Tam olarak anlamanız için uzun bir örnek olacak ama başlıyoruz...

Şu anda bilgisayarınızın başında oturuyor, windows işletim sisteminiz
altında bazı programları kullanıyorsunuz. Muhtemelen Internet Explorer
bunlardan biri. Kullandığınız her program (*.exe *.dll *.ocx ...) hangi
programlama dili ile yazılırsa yazılsın hepside derlenmiş ve ilgili
dosyalar haline dönüştürülmüştürler. Bir program Delphi ile yazılmış ve
derlenmiş (exe uzantılı dosya haline getirilmiş) ise tersi işlem
yapılması, yani programın kodlarına geri döndürülmesi imkansızdır.
Derlenmiş program artık işletim sistemimizin ve makinamızın
işlemcisinin anlayabileceği bir haldedir. Yani bizim makina dili
dediğimiz haldedir. Tamamen iç yapısı elektronik devre elemanlardan
oluşan işlemcimiz bu makina dili halindeki kodları çalıştırabilir.
Başka hiçbir şeyden anlamaz. Bilgisayarlara bu nedenle de aptal makina
denmektedir. Çünkü biz ne emredersek onu işlerler. Makina dili 16 lık
sayı sistemindeki değerlerden oluşur. Bu kodlar sadece sayı
kümelerinden oluştukları için bir insanın bunları anlaması hele hele bu
sayılar üzerinden programlarını yazması nerdeyse imkansızdır...

Fakat insanların karmaşık sayılar yerine kendi konuşma dillerindeki
kelimelerden oluşan bir komut kütüphanesi ile çalışmaları daha
kolaydır. Bunu Basic dilinde rahatlıkla görebilirsiniz. Çünkü Basic
dilindeki komutlar ingilizce bilen bir insan için öğrenme ve akılda
kalma açısından çok kolay bir dildir. Makina dilindeki sayılar yani
kodlar yani programımız bizim için önemlidir. Çünkü bunlar işlemcimiz
üretilirken geliştirilmiş bir komut setine hitap ederler. Bir sonraki
işlemci teknolojisine geçildiğinde komut seti genişletilir ve yeni
komutlar eklenir. Assembly dili bu komut setindeki makina dili
kodlarının insanların biraz daha kolay anlayabileceği harfler üzerinden
gösterimidir. Bu tamamen semboliktir ve her assembly komutu
yazıldığında birebir makina diline çevrilirler.



Peki Assembly bize ne sağladı? :

-Bize işlemcimiz üzerindeki her komuta aracısız erişim sağladı. Yani
kod yazarken muhatabınız işlemci ve üzerinde çalışmakta olduğunuz
işletim sistemidir. (Bu genelde Windows’tur ama başka bir sistemde
olabilir.) Bu size oluşturacağınız programın kodlanması esnasında çok
yüksek bir kod hakimiyeti sağlar. Böylece diğer dillerde aynı işi
yapsanız dahi sizin assembly ile işlemci üzerindeki hakimiyetiniz en
üst düzeydedir ve bunu sizin kadar temiz yapabilecek bir programlama
dili ve/veya derleyici yoktur.

-Yazdığınız her satır kod 1 ila 4 byte civarında olup çok az yer
kaplar. Diğer dillerde yazılan kodlar aynı işi yapsa dahi sizinle
aranızda derleyici bulunmaktadır ve programın işleyişini sağlama almak
amacıyla komutlar arasında ek bilgiler girilmekte ve programınızın
boyutu büyümektedir. Ayrıca diğer dillerdeki komutlar işlemci
üzerindeki komutlarla uyuşmaz ise derleyici bunu dolambaçlı yollardan
işlemciye anlatır ve yazılan bir tek komut makina dilinde yüzlerce
komuta karşılık gelebilir. Herhangi bir dildeki basit komut assembly
ile yazılsa 2 ila 6 kat daha az yer kaplar.

-Yazdığınız programlar (eğer bir algoritma hatası yok ise) diğer
dillerdeki şekillerine göre her zaman daha az yer kaplar. Programın az
yer kaplaması çalışırken daha az bellek tüketmesi; işlemler daha az kod
ile anlatıldığından daha kısa sürede işlemin bitmesi, yani programımız
daha hızlı çalışması anlamına gelir.

Avantajları :

- İşlemcinizin gücünü en iyi şekilde ortaya koyabilecek tek programlama dilidir.
- Cok az yer kapladığı için bilgisayar virüslerin yazımında kullanılırlar.
- Çok hızlı çalıştıkları için işletim sistemlerinde kernel ve donanım
sürücülerinin programlanmasında, hız gerektiren kritik uygulamalarda
kullanılmaktadır.
- Yapısı itibariyle üç boyutlu ekran kartlarında ilgili çizim ve
efektlerin işlenmesi amacıyla hem oyunlar hem de programlar içinde
ekran kartına hitap eden makina dili kodları kullanılmaktadır.
- Herhangi bir amaç doğrultusunda (genelde programların daha hızlı
çalışması için optimize edilirken), herhangi bir programlama dili
altında, o dilin kodları arasında kullanılabilir. Yani diğer dillerle
beraber de kullanabilirsiniz. Sizin uzman olduğunuz dil belki Visual
Basic dir. Ama işin içinden çıkamadınız, assembly bilen bir arkadaşınız
sizin için birkaç kod ekledi ve tamam.
- İyi öğrenildiğinde diğer dillerde karşılaşılan büyük problemlerin
assembly ile basit çözümleri olduğu görülür. Yani başka programlama
dillerde çalışan insanların bu iş imkansız dediği yerde assembly
devreye girer. Bu üstünlük daima var olacaktır...
- Yazdığınız programın kaynak kodlarını tüm dünya ile paylaşsanız dahi
kodlar o kadar karmaşıktır ki insanlar assembly bilse dahi ne işe
yaradığını çözmeleri çok uzun zamanlarını alır. (Açıklayıcı bilgiler
koymadı iseniz) Assembly bilmeyen bir insanın kaynak kodu anlaması
imkansızdır.
- Her program derlendiğinde makina diline dönüşür. Bunlar assembly
kodlarına dönüştürülebilirler. (Buna disassembly olayı denir, bunu
yapan programlar ise disassembler’lar dır.) Bu sayede assembly bilen
bir insan zor da olsa diger programların çalışma şekillerini
inceleyebilir ve üzerlerinde oynama yapabilir. Bu özellik de başka
hiçbir dilde yoktur. Daha ileri gidip programların şifre isteyen
bölümleri değişik yöntemlerle kırılabilir. Serial Generator türü
programlar bu şekilde yapılabilmektedir.
- Zaman geçtikce ve insanlar üreten yerine tüketen bilgisayar
kullanıcıları haline geldikçe bu dili bilmenin ayrıcalığı artmaktadır.

Dezavantajları :

- Dilin öğrenilmesi uzun zaman ve emek ister.
- Yazılan programlar diğer diller göre daha çok satırdan oluşur.
- Yazdığınız programın hangi satırlarının ne iş yaptığını bir süre
sonra anlamayabilirsiniz. Çünkü anlaşılması zor ve karmaşık bir dildir.
Bu nedenle kodların sonuna açıklama bölümleri eklemek iyi bir çözüm
olacaktır.
- İşlemciye birebir bağımlıdır. Yani sonraki sayfalarda anlatılacak
olan kodlar Intel ve uyumlu (AMD, Cyrix, Via) işlemcilerde geçerlidir.
Örneğin Motorola işlemcileri kullanan Macintosh bilgisayarlarda hem
komut setinin hem de işlemci mimarisindeki büyük farklılıklardan dolayı
geçersizdir. Fakat onlarda da bir makina dili tabii ki bir assembly
dili bulunmaktadır. Fakat komutlar daha farklıdır. Bizim ilgi alanımız
intel 386 (i386) üstü ve bunlarla uyumlu işlemcilerdir.




Bilgisayarlar ve Mikroişlemciler

Biraz bilgisayar tarihine değinelim, daha sonra mikroişlemcilere geçeceğiz.

Aslında abaküs’e kadar dayanıyor. Öncelikle matematikteki daha sonra
fen bilimlerinde ve teknolojideki gelişmeler ve yeni teknikler bizi şu
anda bulunduğumuz noktaya getirdi. İlk hesaplayıcılardan sonra Pascal
ve Babbage’in mekanik hesaplayıcıları gelmektedir. Elektronik devre
elemanlarının geliştirilmesi ve tüplü tranzistörlerin sayesinde ilk
elektronik hesaplayıcılar, yani modern bilgisayara giden yol açılmış
oldu. 1936-1951 arasındaki bu donemde 1945 de ENIAC yapıldı. ENIAC ile
işlemler soket bağlantılarının değiştirilmesi ile yaptırılıyor idi.
70bin direnç, 10bin kondansatör, 18bin tüplü tranzistör ve çalışırken
harcanan 150-200 kilowatt enerjisi ile dev ama sadece dört işlem
yeteneği, çok yavaş çalışması, kablolarla programlamanın zorluğu ve çok
sık arıza yapmasıyla da hantal bir cihaz idi.

1948 yılında germanyum, 1954 de silisyum tranzistörler bulundu. Artık
vakum tüpleri yerini yarı iletken tranzistörler aldı. Mikroelektronik
geliştikçe tranzistörler küçüldü ve sonunda bunları tek bir devre
parçasında birleştirme fikri gelişti. Artık entegre devreler yani
çipler karşımızda. Harcanan daha az enerji, daha küçük devreler
taşınabilir radyolar gibi ürünleri beraberinde getirdi.

İntelin ilk ticari amaçlı işlemcisi 1971 yılının 4004 çipi idi. Dört
bitlik bir işlemci olup sadece hesap makinalarında kullanıldı. Bizi
ilgilendiren 1978 yilinda üretilen 8086. Bu işlemci 8bitlik basit ve
yavaş bir işlemcidir. Fakat şu andaki Pentium 4 mimarisi bile geriye
uyumlu olarak bu işlemciyi desteklemektedir. Farkları hız, ek birçok
komut ve yeni teknolojilerdir. Biz de bu 8086 ile başlayan x86 komut
setini programlıyor olacağız. Aşagıda bir ilerleme yer almaktadır.

8086 -> 80186 -> 80286 -> 80386 -> 80486 -> Pentium
-> Pentium Pro -> Pentium !! -> Pentium !!! -> Pentium 4

İntel işlemciler 80386 den itibaren bazı yenilikler getirdiği için (
32bit ve multitasking işlemci ) artık bizim için temel teşkil
etmektedir.
Pentium 4 3000C işlemcisi için biraz açıklama yapalım: Mimari:Pentium 4
İşlemci çekirdek hızı: 3000Mhz (yani bir saniyede 3 milyar komut işler)
C: Veriyolunun 800Mhz olduğu anlamında. Klasik özellikler: 32bit
işlemci, 64 bit veriyolu, 4Gbyte bellek adresleme, Hypertreading
teknolojisi ile çift işlemci gibi çalışma ve gelişmiş mimari
özellikleri ile tek döngüde iki işlem yapabilme özellikleri bulunuyor.

İşlemcimizin 32 bit olması ne demek? Öncelikle bit nedir? 1 byte bilgi
tek karakterden oluşur. Yani notepad içine yazdığınız tek bir ’A’ harfi
1 byte yer kaplar. 1 byte bilgisayarda 8 bit yani 8 tane ’1’ veya ’0’
dan oluşur.

binary 11111111 = decimal 255 eder.
binary 01000001 = decimal 65 eder. Bu değeri içinde saklayan bir
8bitlik saklayıcı ’A’ harfini gösterir. Yani matematiksel değerlerinin
yanında bu 8 bitlik değerler ASCII karakter setine göre belirli bir
karaktere de denk gelmektedir.

İlk sayfada 0C85:0100 B402 MOV AH,02 şeklinde bir satır bulunuyor idi.
Buradaki B402 16lık sayı sistemindeki 2 byte bilgidir. Ve bu makina
dili komutu assembly olarak Mov ah,02 ye denktir. Bu komut ise ah
registerine (işlemcideki 8bit saklayıcılardan biri) 02 hexadecimal
değerini atar. İleride bit düzeyinde işlemler de yapacağımız için 16
lık 10 luk ve 2 lik sayı sistemlerinin birbirine dönüşümlerini bilmek
zorundayız. Örnek bir binary-decimal dönüşümü aşağıdadır.

binary 01001110 için Decimal karşılığı=0*2^7+1*2^6+0*2^5+0*2^4+1*2^3+1*2^2+1*2^ 1+0*2^0=64+8+4+2=78 eder.

Daha önce de belirttiğimiz gibi işlemci sadece matematiksel değerlerden
anlar. İster kod isterse data olsun esas olan bitlerdir. 32 bit
işlemciler 1 döngüde 32 bit yani 4 byte bilgiyi işleyebilme özelliğine
sahiptir. Çarpma, bölme, bellekten işlemciye veri alınması ve
gönderilmesi gibi...

İşlemciler teknik özellikleri yanında iç frekansları ile de
karşılaştırılmaktadır. Pentium 3 1000Mhz bir işlemci saniyede 1 milyar
işlem yapar. Fakat işlemcide her komut aynı sürede tamamlanmaz. Bu
komutun karmaşıklığı ile alakalıdır. İşlemci içinde bir tür sinyal
üreten saat bulunur. Bu işlemcinin hızını tayin eder. İşlenecek olan
komut saat darbesinin verilmesi ile işlem görmeye başlar ve bir sonraki
saat darbesine kadar tamamlanmak zorundadır. İşlemcideki tüm komutlar
için bu geçerlidir.

Register’lar

İşlemcimizin bize sundukları üzerinden program yazdığımız için
işlemcimizi de tanımalıyız. Komut setini yani assembly komutlarını bir
sonraki derste anlatmaya başlayacağız. Registerler işlemci çalışması
sırasında değişik amaçlar için kullanılan değişkenlerdir. Bellekteki
verilere ulaşmak belirli bir zaman gerektirir, fakat registerler
işlemci çekirdeğindedir ve fazladan zaman harcanmadan istenen işleme
göre içerikleri kullanılabilmektedir. Fakat sınırlı sayıda bulunurlar.
Registerler genel amaçlı kullanılabilecekleri gibi bazıları sadece özel
görevleri üstlenmektedir. Bunlar ileride anlatılacaktır. Şimdi i386
uyumlu bir işlemcinin registerlarına bakalım.














<--- 32 bit register --->


EAX

EBX

ECX

EDX

EBP

ESP

ESI

EDI






<--- 16 bit register --->


AH
AL

BH
BL

CH
CL

DH
DL





BP

SP

SI

DI





<--- 16 bit register --->


CS

DS

SS

ES

FS

GS




<--- 32 bit register --->


EIP

EFLAGS













Evet yukarıda işlemci registerlerinin çoğu görülmekte. İlk iki tablo
aslında iç içe girmektedir, fakat bu şekilde daha iyi anlışılacağını
düşündüm. Aşağıda ise bu registerlerin sınıflandırılmış halini
görebilirsiniz.


Data Registers
Pointer Registers
Index Registers
Segment Registers

EAX,EBX,ECX,EDX,AX,BX,CX,DX,AH,AL,BH,BL,CH,CL,DH,D L
EBP,ESP,BP,SP
ESI,EDI,SI,DI
CS,DS,SS,ES,FS,GS



Daha önce söylediğim gibi yukarıdaki 32 bitlik işlemcimiz 8086 tabanlı
olduğu için geriye uyumlu olarak 8086 nın programlarını da
çalıştırabilmelidir. Fakat 8086 işlemcisi 8 bitlik bir işlemcidir. Bu
nedenle gerçekte EAX şeklindeki bir register 32 bittir, fakat bu
registerin ilk 16 bitlik bölümü AX şeklinde ifade edilir. Bu AX
şeklindeki 16 bitlik bölüm ise kendi içinde ilk 8 bitlik bölüm AL,
sonraki 8 bitlik bölüm AH olmak üzere yine alt bölümleri bulunur. Yani
ben 4 byte bilgi depolamak istersem EAX,EBX gibi 32 bitlik; 2 byte
bilgi depolamak istersem AX,BX gibi 16 bit; eger 1 byte bilgi depolamak
istersem AH,AL,BH,BL registerlerini kullanabilirim. Sadece şunu
unutmayın, AX,AH,AL registerleri sadece EAX registerinin alt
bölümleridir. Başka yerde depolanmazlar. Gerekli olduğunda alt
registerlere ulaşılabilir fakat gerçekte esas olan EAX dir. Pointer ve
index registerlerinde de alt bölümler bulunur. Sınıflandırma tablosunu
inceleyiniz. Kafa karıştırma olasılığına karşılık aşağıda registerleri
boyutlarına göre de sınıflandırdım.



32bit registers (4 byte)
16bit registers (2 byte)
8bit registers (1 byte)

EAX,EBX,ECX,EDX,EBP,ESP,ESI,EDI,
EIP,EFLAGS
AX,BX,CX,DX,BP,SP,SI,DI,
CS,DS,SS,ES,FS,GS,IP,FLAGS
AH,AL,BH,BL,CH,CL,DH,DL





Şimdi yukarıdaki registerler ne işe yarar onları öğrenelim ? (Örnekleri bir sonraki Ders içeriğinde yer alacak.)

AX : Akümülatör Registeri, Dörtişlem operasyonlarında kullanılmaktadır.
BX : Base Registeri, Bellek lokasyonlarında baz adres göstericisi
olarak kullanılır, yani bir tür index registeri gibi kullanılabilir.
CX : Counter Registeri, Döngü işlemlerinde sayaç olarak kullanılır, yani döngü kaç defa daha dönecek bunun sayısını tutar.
DX : Data Registeri, Donanım ile yapılan giriş çıkış işlemlerinde kullanılır.

CS : Code Segment Registeri, Segmentler bellekte bir alt bölümü işaret
ederler. Önemli olan içeriklerinin ne olduğudur. Bizim en önemli
segmentimiz kod segmentdir. İçeriğinde ise tahmin edebileceğiniz gibi
yazdığımız programın komutları yer alır. Hem programcı hemde kullanılan
işletim sistemi kod segmentteki komutlar üzerine başka dataların
yazılmayacağının garantisini almalıdır. Aksi taktirde programımız garip
hatalar verir ve kitlenir. Programların sağlıklı çalışmaları için Code
Segment içeriği en önemli noktadır. (NT çekirdeği taşıyan Windows 2000
ve XP işletim sistemleri gelişmiş bellek yönetimleri sayesinde Windows
9x sistemlere göre daha kararlıdırlar. Windows 9x sistemlerde
programlardaki hatalar sistemi çökertebilecek seviyeye çıkabilir. Mavi
ekran hataları bu sebepledir. )
DS : Data Segment Registeri, programımızı yazarken kullandığımız
değişkenler,karakter dizileri ayrıca çalışma anında oluşturulan
değişken tiplerinin tamamı bu segment altında tutulur.
SS : Stack Segment Registeri, Stack çok özel bir data segment tipidir.
Alt programlardan, dll dosyaları içinde bulunan fonksiyonlardan,
windows api fonksiyonlarından kodlar yürütülmeden önce gerekli
değişkenler bu segmente sadece bu amaçla kullanılan bir assembly komutu
ile alınırlar. Daha sonra çağırma işlemi yapılır. Önemli olan çalışma
prensibini anlamaktır. Burada diğer data segmentlerden olduğu gibi
istenilen adresinden veri çekilebilmektedir. Farkı ise stack’a yollanan
son verinin çağırılma esnasında ilk olarak geri dönmesidir. Yani son
giren-ilk çıkar mantığı. (ileride daha ayrıntılı anlatılacak) Veriler
stackin sonundan başına doğru alınırlar. Stacka son yollanan veriyi SP
isimli Stack Pointeri işaret eder.
ES : Extra Data Segment Registeri,Data segment ile aynı özelliklere
sahiptir. Özel olarak bu segmenti kullanan birkaç komut bulunmaktadır.
FS,GS : Bu segment registerleri ihtiyaç olduğu zaman kullanılmaktadır.
Aslında ek olarak kullanılan Data Segment Registerleridir.

BP : Base Pointer, Stack segmentin başlangıç noktasını gösterir. Yani genelde içeriği sıfırdır.
SP : Stack Pointer, Stack segment içine gönderilmiş olan son değerin
(byte) adresini göstermektedir. Stack içine veriler yollandıkça değeri
azalır çünkü veri segmetin sonundan başına doğru alınırlar. Veriler
stackdan çekildikçe değeri artar, böylece eski verileri gösterir, eski
veriler silinmez ama SP değeri değiştiği için işlem hata vermeden
yürümektedir.
***BP ve SP aslında SI ve DI gibi segmentler içindeki verinin adresini
gösterirler. Stack Segmentin özel bir çalışma şekli olduğu için bu
Pointer registerleri özel olarak sadece Stack Segmentin sağlıklı
çalışması için görev yapmaktadır.

SI : Source Index, Data segment veya istenirse başına küçük bir
tanımlama eklenerek diğer data segmentlerdeki verileri de göstermek
için kullanılan bir index (işaretçi) registerdir.
DI : Destination Index, SI ile tamamen aynı özelliklere sahiptir. Fakat
SI ve DI bazı string komutları tarafından kaynak ve hedef işaretçisi
olarak da kullanılmaktadır.

IP : Bir işaretçi registerdir. Çok özel bir işaretçidir. Code Segment
içinde işlenecek bir sonraki komutun yerini işaret eder. Yaptığınız
işten emin olmadan üzerinde oynama yapmayın!
FLAGS : 32 bitlik yine çok özel bir işlevi olan registerdir. Bu
registerin içeriğindeki bitler çok önemlidir. Bazı bitler anlamsızdır,
diğerleri ise daha önce işlenen komutların sonuçları ile ilgili
bilgiler verir. Örneğin CMP komutu ile iki sayı karşılaştırılır ise
sayıların eşit olma veya birinin diğerine göre büyük olması bu register
içindeki bazı bitleri 1 (set) veya 0 (reset) durumuna getirecektir.
Daha sonra kullanılacak bir dallanma komutu ile bu flaglar kontrol
edilerek sonuca göre belirli adreslere dallanmalar yapılır. İçeriğini
biz direkt olarak kullanmayacağız. Bazı komutlar işleyişleri sırasında
bu registeri gizli olarak kullanmaktadırlar.

Aşağıda hangi segmentlerin hangi işaretçi registerler ile kullanılacakları verilmektedir:
CS:IP DS:SI DS: DI SS:BP SS:SP


Debug ve Kullanımı

İster DOS olsun isterse Windows, çalıştırılabilir iki tipte dosya
bulunur. Com veya exe tipindedir. Com tipi dosyalar birebir programın
bellekteki şeklinin aynısıdır. Exe tipi dosyalarda ise programın
başında işletim sisteminin anlayacağı tipte bir başlık bulunur. İşletim
sistemi bu kısımdaki direktiflere göre code, data ve diğer segmentleri
bellekte boş olan yerlere göre hafızaya yükler ve ilgili segmentlerin
adreslerini registerlere aktararak programin ilk komutu ile işlemi
programa bırakır. Com tipi programlarda böyle bir düzenleme yapılmaz,
sadece diskten okunur, boş bir bellek adresine yerleştirilerek yürütme
programa bırakılır. Tabii dos altında olsa idik tam olarak böyle idi.
Windows altında dos için yazılmış olan tüm programlar bir dos emülasyon
penceresi altında sanal bir ortamda çalışırlar. (Com dosyaları 64k dan
daha uzun olamazlar, exe tipi dosyalarda bu tür bir sınırlama olmayıp
gelişmiş özellikler içerirler. Bu nedenlerle exe tip dosyalar daha çok
kullanılırlar.)

Exe tipi programlar derlenerek hazırlabilirler, fakat com tipi
dosyaların derlenmeye ihtiyacı yoktur ve Debug.exe isimli komut satırı
programı ile bunlar programlanabilir. Debug.exe tüm dos ve windows
işletim sistemleri ile birlikte geldiği için ek bir program kurmanıza
gerek yoktur. Tabii bu programı sadece komutların kullanımlarını
görmek, programımızı satır satır çalıştırarak registerleri nasıl
etkilediğini görmek amacıyla kullanacağız. Fakat kullandıkça vazgeçmesi
zor bir programdır, yani bağımlılık yapar. (Şunu unutmamalıyız: Debug
ile 16 bit registerlere ulaşabilir ve bu şekilde program yazabiliriz,
32bit ile çalışmalar bir sonraki bölümden itibaren başlayacaktır.)

Başlat -> Çalıştır yolunu izleyerek command yazıyoruz. Sonra debug
yazıp enterleyin. Karşımıza sadece ’-’ işareti geldi. Artık debug
bizden komut girmemizi bekliyor. Aşağıda ilk programımızı yazdık, şimdi
biraz anlatalım.
Komut satırını açarak debug’a geçiş yaptık. ’a100’ şeklinde bir ifade
var. ’a’ komutu bizim assembly kodlarının girişine başlayacağımızı
bildirir. sonundaki ’100’ ise komutları yazmaya başlayacağımız
adrestir. Debug ile sadece com tipi dosyalar yazılabiliyor ve bu tür
programlar 100h adresinden itibaren yazılırlar. (Debug altında
gireceğimiz tüm matematiksel ifadeler hexadecimal sistemdedir!!! Yani
100h aslında decimal 256’ya denk gelir.)

mov ah,2 : MOV komutu bizim en çok kullanacağımız komutlardan biri.
Sağdaki register içeriğini veya herhangi bir hexadecimal sabit değerin
soldaki registere kaydedilmesidir. Tabii bu durumda ah’ın eski değeri
kaybolur, zaten bizim için şu anda bunun önemi yok. (com tipi
dosyalarda program ilk çalışmaya başladığında çoğu registerin değeri
sıfırdır.)

mov dl,3 : Yukarıdaki MOV komutu gibi burada da bir atama söz konusu. DL isimli 8bit registere 3h değeri kaydediliyor.

int 21, int 20 : Bu komutlar dos kullanıldığı zamanlarda geçerli idi.
Benzer işlemde şu anda windows altında API fonksiyonları görev
yapmaktadır. Bunları bir tür dos işletim sisteminin bize sunduğu hazır
fonksiyonlar olarak görebiliriz. Elbette sadece 20 ve 21 bulunmamakta.
Fakat bunlara değinmeyeceğiz. (int=interrupt) Interrupt 20 parametresiz
çağırılır ve bizim com tipi programımızı sonlandırır. Interrupt 21 dos
ile gelen dev bir fonksiyonlar kütüphanesidir. Hangi numaralı
fonksiyonun çağırılacağını ah registerine koymak zorundayız.
Fonksiyonun tipine göre istenen başka değerler bulunuyor ise bunlar da
ilgili registerlara atanmalıdır. Daha sonra interrup çağrısı yapılır.
Biz iki numaralı fonksiyonu (yani ekrana karakter yollama fonksiyonu)
çağırıyoruz, bunun için ah a 2 atadık. Daha sonra ASCII karakter
tablosuna göre hangi değer ekrana getirilecek ise onun hexadecimal
değerini DL registerine atıyoruz. (Burada 3h kalp şeklinde bir
karakter, eğer 41h değeri atanırsa ’A’ harfi ekrana basılır.)
(Bunlardan sonraki satırı ENTER ile boş geçin.)

g : ile programa çalışma emri veriliyor. Gördüğünüz gibi bir karakter
ekrana basılıp program int 20 ye geldiğinde normal olarak sonlanıyor.

n : ile programımıza isim veriyoruz. r cx ile cx registerinin değerini
değiştirerek 8 giriyoruz çünkü programımızın son satırı 0108 adresini
gösteriyor. Ilk satır 0100 ise arada 8 byte yokmu? Yani programımız
8byte uzunluğunda ve biz bunu cx’e aktararak diske kaydedilecek
programın boyutunu belirtiyoruz ve w ile işlem tamamlanıyor. Artık q
komutunu verip Debug’dan çıkın ve bulunduğunuz dizinde 8 byte
uzunluğunda bir kalp.com isimli program var mı bir bakın. Veya hemen
kalp yazıp ekran çıktısının debug içinde g komutu ile aldığımızın
aynısı olduğunu görebilirsiniz. Bu bizim ilk programımız oldu.

Assembly Nedir? Debug02ci1

Yukarıdaki çalışma yine aynı program üzerinde yapıldı. Burada t (trace,
izle) komutu ile programımızı satır satır çalıştırdık ve registerler
üzerindeki etkilerine baktık. Interruptlar birer dev kod bloğu olduğuna
göre ve bunları da trace eder isek sayfalar sonra içinde
çıkabileceğimiz için bunları pas geçmek için p kullanıldı. Ilk komut
işlendikten sonra ekrana ilk gelen bölümü inceleyelim. Ilk komut mov
ah,2 idi. Gördüğünüz gibi AX=0200 bölümünde AX in üst 8 bitine yani
AH’a 2 değeri atanmış. Burada dikkat ederseniz DS,ES,SS,CS değerleri
yani segment registerları aynı blok adresini gösteriyorlar. Yani com
tipi dosyalarda kodlar ile datalar aynı yerde bulunuyor. Bu da bize
program yazarken dikkatli olmamız gerektiği anlamında önemli bir not.
IP pointeri daima sırada işlenecek olan komıtu gösterir. Ilk komut
işlendiğine göre 0102 değerini gösteriyor. IP nin hemen sağ tarafındaki
ifadeler flagların durumlarını göstermektedir, şu anda önemli değil.
Üçüncü satırda sırayla şunlar yer alıyor: CS:IP


Ikinci trace’de DL ye 3 değerinin aktarılmış olduğu rahatlıkla
görülebilir. Bundan sonraki p komutu ile int 21 işleme girer ve ekranda
görülen kalp işareti geliyor. int 20 de programdan çıkılıyor. Bu basit
bir örnek oldu, daha karmaşık bir örnek inceleyelim.

Assembly Nedir? Debug03em3

mov ah,2 : Interrupt 21 içindeki 2 numaralı fonksiyon yani ekrana karakter basmamız için atıyoruz.

mov cx,FF : Şu ana kadar görmediğimiz döngü işlemi için kullanılacak.
FF yani decimal 255 değeri CX e atanıyor. Aşağıdaki loop
komutuna gelindiğinde cx in değeri bir azaltılıyor ve sıfıra eşit değil
ise değerine atlıyor program. CX içindeki sayı kadar bu
loop döngüsü devam ediyor, yani 255 defa. CX sıfıra eşit olduğunda ise
hiçbir işlem yapılmıyor ve bir alttaki komut ile programa devam
ediliyor. Diyebiliriz ki LOOP komutu gizli olarak cx registerini
kullanmaktadır.

inc dl : inc komutu karşısındaki registerin değerini bir artırır.
Biliyorsunuz ki ekrana gönderilecek karakter dl içinde. Biz 255 döngü
içinde 1 ila 255 arasındaki tüm ASCII karakterleri ekrana basmak
istiyoruz. Bunun için toplama işlemi de yapabilirdik (add dl,1) fakat
bu işlemin okunurluğu daha iyidir.

int 21 : Ekrana karakter yazma fonksiyonu çağırılıyor.

loop 105 : CX sıfıra eşit değil ise 105 adresine zıpla.

int 20 : Programdan çık.

Aşağıda g (go) komutu ile çıktı alınıyor. Tabii buradaki karakter seti
dos altındaki; windows altındaki ile uyuşmayabilir. Daha sonra ise
ascii.com şeklinde kaydediliyor.



Aşağıda bazı assembly komutları ve açıklamaları bulunuyor:

MOV : Değer aktarmak için kullanılır. mov ah,2 mov ax,FFFF mov bx,cx
mov dl,bh mov [200],ah mov dl,[382] gibi. (Köşeli parantez
’adresindeki’ anlamındadır. Yani ah içeriğini 200 adresine transfer et
gibi.)
XCHG : İki registerin içeriklerini karşılıklı olarak değiştirmelerini sağlar. xchg ah,bh xchg ax,dx gibi.
ADD : İki değerin toplanması amacıyla kullanılır. Sonuç değer soldaki
registere kaydedilir. add ax,bx add ah,AF add dl,1 add al,ah gibi.
SUB : Çıkarma işlemi yapar. Sonuç ilk registere kaydedilir. sub ah,1 sub ax,bx sub cx,10 gibi.
MUL : Çarpma işlemi yapar. Tabii ki tüm işlemlerde olduğu gibi değerler
ve sonuçlar hexadecimaldir. 3 farklı durumda incelenebilir.





8bit*8bit yani byte*byte : Çarpılacak değerlerden biri al ye
kaydedilir mov al,5F gibi. Daha sonra çarpma işlemi yapılır, mul bl
gibi. Sonuç ise ax registerindedir. (ax=al*bl işlemi)
16bit*16bit yani word*word : Çarpılacak değerlerden biri ax ye
kaydedilir mov ax,05FF gibi. Daha sonra çarpma işlemi yapılır, mul bx
gibi. Sonuç ise dx,ax ikilisine aktarılmıştır. Yani üst 16bitlik kısım
dx de, alt 16bitlik kısım ise ax dedir. (dx,ax=ax*bx)
32bit*32bit yani dword*dword Çarpılacak değerlerden biri eax ye
kaydedilir mov eax,A055FF10 gibi. Daha sonra çarpma işlemi yapılır, mul
ebx gibi. Sonuç ise edx,eax ikilisine aktarılmıştır. Yani üst 32bitlik
kısım edx de, alt 32bitlik kısım ise eax dedir. (edx,eax=eax,ebx)






DIV : Bölme işlemi için kullanılır. Ayrıntılarına girmiyorum.
INC : Register içeriğini bir artırır. inc ah gibi
DEC : Register içeriğini bir azaltır. dec cx gibi.
NEG : Sayının ikili tamamlayıcısını bulur. Örneğin al de 11110000
binary değeri bulunuyor ise neg al işleminden sonra bu değer 00001111
olur.
PUSH : Stack a yani stack segmente değer göndermek için kullanılır. push ax gibi.
POP : Stack dan değer çekmek için kullanılır. pop cx gibi.


Windows Altında Win32Assembly Programlama

Artık masm ile nasıl program yazılır bir gözatalım. Aşağıdaki küçük bir windows uygulaması yer almakta:



Yukarıdaki ilk örnek qeditor.exe ile derlenebilecek haldedir. Biz eğer
notepad kullanmış olsaydık bu şekilde kodlayacak idik. Ben derledim ve
boyutu 2.5kbyte olan bir exe dosyası oluştu. Yukarıdaki hem soldaki
hemde sağdaki assembly kodu aynı işi yapıyor. Yaptığı iş baslik ismi
ile belirtilen başlığa sahip, yazi ismi ile yine data segmentte
belirtilen yazıya sahip bir mesaj kutusu gösteriyor. OK’e tıklandıktan
sonra program sonlanıyor. İsterseniz hemen açıklamaya başlayayım. İlk
üç satıra uzun süre hiç dokunmayacaksınız, burayı geçiyorum. Include
satırları ile içinde windows api fonksiyonlarının ve bazı sabit
değerlerin isimleri bulunan inc uzantılı dosyaları tanımlıyoruz.
Includelib fonksiyonu ile kullandığımız api fonksiyonlarını içeren
kütüphaneleri tanımlıyoruz. Windows.inc dosyasında NULL ve MB_OK
tanımlamalarının matematiksel eşitlikleri bulunuyor. Birçok özel
durumun hangi sayılar ile belirtildiğini ezberlemektense bunların
karşılıklarını bilmek daha kolaydır, hemde programın okunurluğunu
artırır. .data ile data segment tanımlanıyor ve bu data segment içinde
baslik ve yazi adreslerinde ilgili string ifadeler yer alıyor. Dikkat
ederseniz stringlerin bittiğini belirtmek için ayrıca 0h degeri
ekleniyor. Daha sonra .code ifadesi ile cede segment tanımlanıyor.
start: ve end start ifadeleri arasına kodlarımızı yazıyoruz. Dört adet
push komutu alt alta yazılmış. PUSH komutu ile stack segmente bazı
değerler gönderiyoruz. Bunlar mesaj kutusu ile ilgili özellikler. İlk
özellik mesaj kutusunda sadece OK tuşu bulunacağı anlamında. İkinci
özellik olan mesajın başlık bölümünde yer alacak yazının adresini
stacka yolluyoruz. (adresi anlamına gelen offset terimi kullanılmıştır)
Üçüncü yollanan özellik mesaj olarak gösterilecek string ifadenin
adresi. Son yollanan ifade NULL yani sıfırdır, buraya bir değer
girmemize şu anda gerek yok. Gerekli parametreler stacka yollandıktan
sonra fonksiyonumuzu çağırıyoruz. CALL komutu bir fonksiyonun yada bir
altprogramın çağırılmasında kullanılır. Çağırılan yerdeki işler
bittikten sonra programımız bir sonraki ifade ile devam edecektir.
Fonksiyonumuz MessageBox apisidir . Bu api user32.inc içinde
tanımlanmış ve ilgi kutuphane user32.lib eklenmiştir. Bu apiyi
kullandığımızı belirtmek için yukarıdaki ifadeleri include ile
tanımlamaktayız. Daha sonraki bölümde programdan çıkış kodları
bulunuyor. Öncelikle çıkış kodu stacka yollanır. Normal sonlanmalarda
bu NULL yani sıfırdır. Daha sonra kernel32.inc ve kernel32.lib ile
tanımladığımız fonksiyonlardan ExitProcess çağırılıyor.

İşletim sistemimizde user32.dll içinde MesageBox apisi, kernel32.dll
içinde ise ExitProcess apisi bulunmaktadır. Dos altında yaptığımız
interrup çağrıları gibi windows altında api fonksiyonları bulunur.
Bunlar disk erişiminden, ekrana resim çizdirmeye, buttonlar ve
kutucuklar hazırlamaya kadar binlerce fonksiyon içeririler. Tabii
sadece bu iki dll dosyasıyla sınırlı değil apiler. Ayrıca yukarıdaki
komutları yazarken dikkatli olmanız gerekiyor. Derleyicimiz büyük küçük
harf ayrımı yapabiliyor. Özellikle api fonksiyonların isimlerini aynen
yazın.

Soldaki kod ise işlev olarak aynıdır. Farkı ise MAsmEd altında
yukarıdaki gibi yazılması yeterlidir. Include tanımlamalarını programda
sol taraftaki ağaç şeklindeki kısımdan ekleyerek yapıyoruz. Data
segmentin içeriği aynı. Code segmentde ise küçük bir değişiklik var.
Alt alta yazdiğimiz fonksiyon çağırma işinde call yerine invoke ile tek
satırda tüm parametreleri yazdık. Böylece daha kolay okunur oldu. Bunu
qeditor.exe içinde de yapabilirdik, yinede eski şekilde kullanılan
örnekler daha çok olduğu için ikisini de göstermek istedim. Yoksa yazım
farkından başka ikiside aynen ilk örnekteki gibi çalışmaktadır. Birde
editörümüz programımız için ikon ve ek bazı versiyon bilgileri
eklemektedir. Bu nedenle editör içinden derlenen aynı program 5.5kbyte
boyuta sahip olacaktır.
Sayfa başına dön Aşağa gitmek
http://www.refleksforum.com
 
Assembly Nedir?
Sayfa başına dön 
1 sayfadaki 1 sayfası
 Similar topics
-
» Assembly Giriş
» Assembly Giriş-2
» Assembly Komutlari
» Assembly Komutlari -2
» Assembly Programlama Dili

Bu forumun müsaadesi var:Bu forumdaki mesajlara cevap veremezsiniz
|Refleks|-Oyun,Tasarım,Film,Program,Tek link,İndir :: Bilgisayar Dersleri :: Assembly-
Buraya geçin: