Seversintabi.com Türkiye'nin En Büyük Forumu Bence Seversin Tabi
 

Go Back   Seversintabi.com Türkiye'nin En Büyük Forumu Bence Seversin Tabi > Eğitim - Öğretim > bilgisayar
Yardım Topluluk Takvim Bugünki Mesajlar Arama

gaziantep escort gaziantep escort
youtube beğeni hilesi
Cevapla

 

LinkBack Seçenekler Stil
  #1  
Alt 2 October 2009, 01:31
Syst3m - ait Kullanıcı Resmi (Avatar)
Root Administrator
 
Kayıt Tarihi: 26 July 2008
Mesajlar: 3,557
Konular:
Aldığı Beğeni: 0 xx
Beğendiği Mesajlar: 0 xx
Standart Assembly

Giriş


Öncelikle hemen söyleyeyim bu yazı programlamayla EN AZ orta seviye ilgilenenlere yöneliktir. Yani bu kritere uymuyorsanız bence hiç bulaşmayın, sonra program yazma işinden tiksinebilirsiniz . Tabi tiksinme kısmı şaka ama yine de size çok sıkıcı gelebilir. Neyse uzatmadan başlayalım yazımıza.
Programlarınızı yazdığınız ortamları merak ettiniz mi hiç? Acaba onlar nasıl yapıldılar? Ya da ilk programlama dili nasıl ve hangi dille yazıldı(biliyorum biraz garip bir cümle oldu)? İşte bütün bu sorulara genel olarak verilebilecek cevap ASSEMBLY'dir. Assembly, aslında makina dili diye de geçer. Bu dili kullanırken -ki aslında tam olarak bir dil demek de yanlış- işlemcinin temel komut setinde ne varsa onları kullanırsınız. Aynı zamanda bildiğiniz şekilde değişken oluşturma ve yönetme şansınız da yoktur(Örn "int i=10;" gibi komutlarınız yok). Tabi bunlar yüzeysel yorumlar. Çünkü Assembly kullanırken bütün bunları -birçok fonksiyon, değişken yönetimi vs.- siz yaparsınız. Yani bir değişkenin saklanacağı bellek adresi, uzunluğu vs. tamamen sizin denetiminiz ve sorumluluğunuzdadır.
Şimdi önce isterseniz gelin programlama dillerinin sınıflandırılmasına bakalım. Programlama dilleri makinaya yakınlığından insana yakınlığına göre sıralanır. Mesela .NET dillerinden C# insana en yakın dillerden biridir. Bir çok alt seviye işlem derleyici tarafından otomatik yapılır veya yapılması için gerekli kod programa eklenir. Bunun yanında C en alt seviye dillerden biridir. Bellek denetimi gibi şeyler programcıya bırakılmıştır ama bu dille yapabilecekleriniz ve alacağınız performans C#'tan çok daha fazla olacaktır. İşte assembly bu sınıflandırmada makinaya en yakın yerde bulunuyor. Eğer bu dili iyi öğrenirseniz ve kullanabilirseniz deyim yerindeyse bilgisayara takla bile attırabilirsiniz.
Bilgisayarlar verileri 2'lik sistemde işler ancak 16'lık sistemde saklarlar. Örneğin 2 sayıyı toplamak istediğinizde bunlar işlemciye bitler şeklinde iletilir ki bu 2'lik sistemdir. Ancak bunları bir dosyaya yazmak isterseniz bu sefer bir byte'lık alanlara yazarsınız ki bu alanlardaki bilgiler de 16'lık sistemde saklanır. Biz de bilgisayarda artık EN ALT seviyede uğraşacağımıza göre bu sistemleri iyi bilmeli, bu sistemler ve 10'luk sistem arasındaki dönüşümleri rahatça yapabilmeliyiz.
Bilgisayarda saklanan ve işlenen verilerden bahsetmişken hemen bunların çalışan programlar için nerelerde yapıldığına bakalım. Normal dillerle yazılan programların tamamı değişkenleri bellekte saklar. Her değişkene ait bir bellek adresi vardır. Hatta pointerlar'la haşır neşir olanlar bu bellek adresilerini anımsayacaklardır. İşte assembly kullanırken bu pointerlar bizim değişkenlerimizi temsil edecek dersek çok da yanlış olmaz. Ancak işlemci komutları genelde doğrudan bellek üzerinde işlem yapmak yapmak yerine genelde REGISTER adını verdiğimiz işlemci çekirdeği üzerindeki sabit değişkenler üzerinde değişiklikler yaparlar.
Bellekle ilgili bilmeniz gereken bir başka şey ise belleğin segmentlere ayrılmış olduğudur. Segment sözcüğünü dilimize kabaca KATMAN olarak çevirebiliriz. Bu katmanlarda benzer tip veriler bir arada tutulur. Örneğin Code Segment(CS)'ta programınızın kodları bulunurken Data Segment(DS)'ta kullandığınız bazı değişkenlerin verileri tutulur. Bunların yanında Stack Segment(SS) ve Extra Segment(ES) gibi başka katmanlar da bulunur. Tüm bu katmanların başlangıç adresleri yanlarında parantez içinde belirttiğim kısaltmalarla aynı adlardaki özel registerlarda tutulur. Bunları yeri geldiğinde göreceğiz. Segmentlerin içindeki hücrelere ulaşmak için de offsetleri(adresleri) kullanırız. Veri yazma ve oku işlemleri DS üzerinde yapılır. O zaman biz bir bellek okuması veya yazması yapacağımız zaman sadece işlemi yapacağımız offseti bilmek zorundayız. İşlemci otomatik olarak DS'de tutlan değere bizim verdiğmiz offset değerini ekler ve ilgili hücreye veriyi yazar yada bu hücreden veriyi okur.
Assembly dilindeki komutlar yani işlemcinin temel komutları genelde 2 parametre kullanır -ki bunlara artık OPERAND diyeceğiz- ve bunlar register adı, bellek bölgesi ya da sabit bir sayı olabilirler. Örnek vermek gerekirse: MOV komutu bri register ya da bellek bölgesine değer atamak için kullanılır. İlk operand atama yapılacak bellek bölgesi ya da register adı, ikinci operand da oraya atanacak değeri içeren bir başka bellek bölgesi, register ya da sabit sayı olabilir. Yeri gelmişken operandları ayırmak için aralarına ","(yazıyla=virgül, rakamla=?!?! ) koyuluyor. O zaman offseti 100 olan bellek bölgesine 10 değerini atamak için "MOV [$64],$0A" komutunu vermemiz gerekiyor. Dikkat ettiyseniz 100 yerine $64 ve 10 yerine de $0A yazdım. Çoğu assembler(asm kodlarını derleyen program) direk onluk tabandaki sayıları kabul eder ve siz 16'lık tabanda bir sayı girmek istediğiniz zaman başına $ işaretini koymanızı ister. Ancak debug gibi basit ve alt seviye bir derleyici kullanırsanız bütün sayılar standart oalrak 16'lık sitemde yorumlanacaktır. Bu arada komutta da gördüğünüz gibi bellek bölgelerine ulaşmak veya oralarda işlem yapmak için offsetini köşeli parantez içinde yazmamız gerekiyor. Ve son olarak o komut aslında hatalı. Çünkü bellek bölgesine byte cinsinden mi word(2 byte'lık veri) cinsinden mi yazacağımızı belirtmedik. O ne ki derseniz hemen açıklayayım. Bellek bölgeleri aslında 1 word'lük kapasiteye sahiptirler ancak oralara sabit sayılar atanırken 1 byte uzunluğundaki veriler de yazılabilir. Bunu açıklığa kavuşturmak için operandlardan önce "BYTE PTR" ya da "WORD PTR" yazmamız gerekiyor. Vay be, bir komutla amma çok şey anlatmış oldum!
Aslında buraya öyle detaylı bir kullanım rehberi ya da birçok komutun kullanım şeklini falan yazmayı düşünmüyorum. Çünkü hem ben o konuda anlatabilecek kadar yetkin değilim hem de zaten bu yazının amacı giriş yapmanızı sağlamak. Zaten sadece assembly kullanarak bir program yazmak aslında biraz çılgınlık (kabul ediyorum zamanında 16bitlik programlar yazdık biz arkadaşımla ama cidden kafayı yeme noktasına geldik ). Bu sebeple buradan öğrendiğiniz genel bilgiler ve komutları öğrenebileceğiniz bir kaynağın da yardımıyla programlarınızda hız artışı veya boyut azaltışı(!) yapabilirsiniz.
Bu kadar gevezelikten sonra genel kullanım ve birkaç komut açıklamsıyla yazımızı bitrelim. Daha önce de dediğim gibi burada komutlardan sonra operand giriyorsunuz. Bazı komutlar operandsız da olabiliyor. Ve bir komut en çok 2 operand alabiliyor(aslında daha çok alan da olabilir ama bildiğim kadarıyla 2 ile sınırlı). Daha önce bahsettiğim MOV komutu 2 operand alır. İlk operand atama yapılacak yeri belirtirken ikinci operand atama yapılacak değeri belirtir. Buraya sabit bir sayı yazabileceğinizi gibi birbellek bölgesi ya da register adı da yazabilirsiniz.
XOR komutu ilk operand ile ikinci operandı XOR mantıksal işleminden geçirir ve sonucu ilk operanda atar. AND, OR gibi diğre mantıksal operasyon komutları da aynı şekilde çalışır.({a:=a xor b} deyimi assemblyde {xor a,b}'ye denk gelir)
PUSH komutu arkasından verilen operandın değerini bellek yığınına atar ve arkasından çağırılan POP komutuyla bu değeri POP komutunun operandına geri yükler. Yanlız burada işlemin sırayla olduğunu unutmamanız gerekiyor. Yani
PUSH EAX
PUSH EBX
.
.
POP EAX
POP EBX
gibi bir komut yazarsanız EAX'ın değeri EBX'e, EBX'in değeri de EAX'a atanmış olur. Çünkü en son EBX'in push edilmesine rağmen ilk POP işleminde EAX kullanıldı. Özetlersek ilk giren son çıkar ya da son giren ilk çıkar diyebiliriz.
CMP komutu kıyaslama yapmak için kullanılır. Verilen ilk opranddan ikinci operand çıkartılır ancak operandların değerlerinde bir değişiklik olmaz. Bu işlem sadece FLAG adı verilen bazı kontrol bitlerinin değerlerinin değişmesine sebep olur ki bu da zaten kıyaslama sonucunda yapılacak işlemi berlemek için yeterlidir. Şöyle ki: burada BASIC'tenbildiğiniz "GO TO"ya benzer bir yapı kullanılıyor. Yani şu şöyleyse buraya git ve oradan devam et gibi bir yapı var. Bunları da GO TO değil JMP, JNZ gibi atlama komutlarıyla yapıyorsunuz. JMP komutu hiçbir koşul gözetmeden operand olarak verilen adrese atlar ve oradan devam eder. JNZ ise "Zero Flag"i olarak geçen ve son işlemin sonucu 0 ise değeri 1 yapılan bir bitin değerine göre atlama yapar. CMP işleminde de iki operandın değeri birbirinden çıkarıldığında sonuç sıfır ise bu iki değer birbirine eşit demektir ki bu durumda JNZ komutu(Jump if Not Zero) hiçbirşey yapmaz çünkü "Zero Flag"i 1'dir. Yani sonuç sıfırdır. JZ komutu ise JNZ'nin tam aksine Jump if Zero yani sonuç sıfırsa şu adrese git anlamına gelir. Yine az önceki durumu düşünürsek bu komutu kulanırsanız program belirtilen adrese sıçrayacak ve buradan devam edecektir.
Son olarak for ve/veya while döngülerine karşılık gelen LOOP komutunu da verelim. For döngülerinde kullandığınız değişken sanırım genel de "i" oluyor. Burada ise bu iş için standart olarak ECX register'ı kullanılıyor. Bu register'a döngünün kaç kez çalıştırlacağını atadıktan sonra işletilecek komutların sonuna LOOP {adres} komutunu yazıp adres olarak da komutların başlangıç adresini verirseniz tam bir for döngüsü elde etmiş olacaksınız. Yalnız burada dikkat etmeniz gereken birkaç nokta var. Öncelikle döngü komutu içerisinde ASLA ECX'in değerini değiştirmemelisiniz. Değiştirmek zorunda kalırsanız da mutlaka PUSH ve POP komutlarını gerekli şekilde kullanıp orijinal değerini geri döndürmeniz gerekir. Aksi takdirde döngünün uzunluğu alakasız şekilde değişebilir. İkinci olarak, LOOP'a operand olarak verdiğiniz adres ECX'registerına döngü sayısını atadığınız yerden sonra olmazsa programınız sonsuz döngüye girer. LOOP'un 2 farklı versiyonu daha var: LOOPZ ve LOOPNZ. Bunlar da hem ECX'in değerine bakıyorlar hem de "Zero Flag"inin değerine. LOOPZ, Loop if zero; LOOPNZ ise loop if not zero yani LOOPZ sıfır olduğu sürece, LOOPNZ de sıfır olmadığı sürece döngüye devam et anlamına geliyor. Eğer döngü içinde bir CMP işlemi varsa bu komutlardan birini kullanarak döngü sayısı bitmeden döngüden çıkılmasınıa sağlayabilirsiniz.(Bu da döngü içinde kullandığımız "break;" komutuna benziyor.)
Alıntı ile Cevapla
Cevapla



Benzer Konular

Konu Konuyu Başlatan Forum Cevaplar Son Mesaj
12 Eylül'ün Sonuçları Alkan Tarih Hakkında Herşey 0 21 June 2009 20:39


Saat: 16:13


Telif Hakları vBulletin® v3.8.9 Copyright ©2000 - 2024, ve
Jelsoft Enterprises Ltd.'e Aittir.
gaziantep escort bayan gaziantep escort
antalya haber sex hikayeleri aresbet giriş vegasslotguncel.com herabetguncel.com ikili opsiyon bahis vegasslotyeniadresi.com vegasslotadresi.com vegasslotcanli.com getirbett.com getirbetgir.com
ankara escort ankara escort ankara escort bayan escort ankara ankara escort çankaya escort ankara otele gelen escort eryaman escort adana escort eryaman escort kızılay escort çankaya escort kızılay escort ankara eskort

Search Engine Friendly URLs by vBSEO 3.6.0 PL2