Makine dili hepimiz az çok duymuşuzdur bunu. Şimdi sizlere kendi yaptığımız bir sırayla açıklayacağım.
Ama önce bunlar lazım
1. Bilgisayarınız olsun ?
2. İçinde Windows ve DOS, bunlar içinde programlama dilleri olsun
3. matematiğiniz olsun ve mantık hesaplarını biliniz
4. elektronik bilginiz olsun (sayısal elektroniğinizde)
5. İngilizce’niz olsun
6. biraz çalışan beyin
Bir bilgisayarınız olmalı elbette
Bu işi yapmak için elinizde bulunacak eski bir 8086 bilgisayar yeterli olur. Şimdi soracaksınız benim bilgisayarım olur mu diye. Olur, çünkü bu işlemci temelli olması yeterli bilgisayarınızın ki şu an çıkan Pentium 4’ler bile bu temeli kullanır.
Şimdi asıl içeriğimize geçelim. Eğer temeliniz yoksa bu yazıyı okumanın sadece kafanızı karıştıracağını düşünüyorum.
INDEKS
1. Programlama Dilleri
2. Sayısal Elektronik ve Mantık Hesaplamaları
3. Assembly’e Giriş
3.1. Hafıza ve İşlemci (RAM & CPU)
3.2. Genel Amaçlı Kaydediciler (General Purpose Register)
3.2.1. AX, BX, CX, DX
3.2.2. DS, DS, SS, ES
3.2.3. SP, BP, SI, DI, IP
3.2.4. Program Status Word (Flag Register)
3.3. Genel Komutlar
3.3.1. MOV
3.3.2. INC
3.3.3. DEC
3.3.4. INT
3.3.5. CMP
3.3.6. JUMP .............
3.3.7. CALL – RET
3.4. Prototip Program ve Op Code için örnekler
1. Programlama Dilleri
Bilgisayarınıza işlem yaptırabilmek için ona birbiriyle bağıntılı toplu emirler vermeniz gerekir. Örnek verirsem. Susadın mı ? evet veya hayır olarak iki cevap gelir. Evet ise su iç hayırsa işlem yapma. Bu olay bilgisayar ile aranızda ortak bir dil kurulmasının gerektirir. Bu dil hanginize daha yakınsa diğeri daha çok zorlanır. Bir bilgisayarın anlayacağı en iyi dil makine dilidir. Bu dilde komutlar ve tanımlar yerini bilgi şekline dönüştürür. Yukarıdaki örneği makine dili için şöyle yaparız. Musluğu aç bardağı musluğun altına tut dolunca bardağı çek ve musluğu kapat. İşte bu ayrımdan dolayı dil seviyeleri ortaya çıkar.
2. Sayısal Elektronik ve Mantık Hesaplamaları
Hepimizin bildiği modern matematikte 10’luk sayı sistemini kullanırız. Fakat bizim kullandığımız sayı sistemi haricinde bilmemiz gereken 3 adet sayı sistemi daha var. İlk olarak kendi kullandığımız sistemi inceleyelim.
0, 1, 2, 3, 4, 5, 6, 7, 8, 9 : Bizim kullandığımız sayı sisteminde 10 rakam vardır. Bu sistemin adı 10’luk taban ya da Decimal sayı sistemi olarak bilinir.
Şimdi diğerlerine bakalım
0, 1 : Binary (2’lik) sayı sistemi
0, 1, 2, 3, 4, 5, 6, 7 : Octal (8’lik) sayı sistemi
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F : Hexadecimal (16’lık) sayı sistemi
Aslında tüm sistemler aynı sayılır. Sadece kullanım biçimi olarak değişiklik gösterir. Şuna açıklık getiriyim bu sayı sistemleri birbirlerine dönüşebilirler. Genelde şu vardır BINARY sayı sistemi ile 1’den büyük rakamlar nasıl yazılıyor. Yazılır ? bunu maalesef burada anlatamayacağım. Ama tekrar söylüyorum tüm sayı sistemleri ile modern matematikte kullandığımız işlemleri yapabilirsiniz.
Sorumuzun cevabı : Bu sistemleri bilgisayar kullanır. Bilgisayar tüm bilgileri BINARY (2’lik sayı tabanı) olarak alır. Bunlar HEXADECIMAL kalıplar biçimli kullanılır. Örneğin veriyi byte’ler şeklinde okur fakat kendi iletişim trafiği içinde bunu muhakkak BINARY sisteme çevirir.
3. Assembly’e Giriş
3.1. Hafıza ve İşlemci (RAM & CPU)
Hafıza (Random Access Memory) (Rasgele Erişimli Bellek)
Üzerinde çalışılan bir masa gibi düşünebiliriz. İşlemlerimiz için bu bölgeyi kullanılırız.
İşlemci (Central Proccess Unit) (Merkezi İşlem Birimi)
İşlemlerimizi yaptırdığımız yer bu kısımdır.
Çalışmaları
Hadi artık başlayalım;
Bir işlem yaptırmak nasıl oluyor bununla başlayalım. Şimdi bu karmaşık konuyu kafanızda canlandırabilmeniz için örnekler veriyorum.
Bir bilgiyi ekrana yazdıralım.
Öncelikle bu iş için hafızada bir bilgi olduğunu varsayalım. İşlemcimize şunu demeliyiz hafızanın şu bölgesindeki bilgiyi tut ve ekranın şu kısmına yaz.
Bir bilgiyi okutalım.
(bunu da otomatik yapabiliyor ama biz incelediğimiz için teorikleştiriyoruz)
İşlemcimiz klavyeden gelen her bilgiyi okusun. Sonra bunu hafızaya yerleştirsin ve ekranda da belirtsin.
Tabii yapabileceklerimiz bununla sınırlı değil işlemcimiz ile tüm donanımlara ait kontrolleri gelişmiş şekilde denetleyip, yönetebiliyoruz. Şimdi yukarıdaki iki örneğe tekrar dönelim dikkatinizi çekti mi bilmiyorum ama anlatayım. Biz önce bilgisayara hazır veriyi işlettik ikinci örnekteyse bilgisayardan bilgi alıp daha sonra bunu yazdırttık yani biz işlemciye hem bilgilerimizi işlettirebiliyoruz hem de işlemciden istediğimiz bir bilgiyi alabiliyoruz. Ya da bir işlem içinde ikisini de gerçekleştirebiliyoruz. Biz buna kesme isteği diyoruz.
IRQ (Interrupt Request) {Kesme İsteği}
Bilgisayara işlem yaptırırken bunu Kesme İstekleri ile yapıyoruz. Yine örnekliyorum; Aşağıda bilgisayarın tarihini değiştiriyoruz.
X değeri = 15 (ayın günü)
Y değeri = 3 (ay)
Z değeri = 2001 (yıl)
Kesme İsteği Kodu
İlgili Kesmeyi Yap
Gördüğünüz gibi örnekte bilgisayara parametre verip bunları işlemesini istedik şimdide biz bilgisayardan veri alalım.
Kesme İsteği Kodu
İlgili Kesmeyi Yap
X değeri = gün (yani X günü gösteriyor)
Y değeri = ay (Y ayı gösteriyor)
Z değeri = yıl (Z yılı gösteriyor)
Şimdide bilgisayardan kesme ile return code (dönüş kodları) elde ettik.
Örneklerden de anlaşılabileceği gibi kesme ile işlemlerimizi yaptırabiliyoruz. Yukarıda gördüğünüz örnekleri makine diline çevirelim ve bu bilgileri tekrar incelemeye koyulalım.
mov DL, bugun
mov DH, ay
mov CX, sene
mov AH, 2B h
int 21 h
mov AH, 2A h
int 21 h
mov gun, AL h
mov ay, DH h
mov sene, CX h
Yukarıdaki renklerin ne olduğunu hemen açıklayayım.
Mavi renkler : mov ve int komutu
mov (move) komutu. Buradaki görevi eşittir işareti gibi düşünebilirsiniz. Yani MOV AX, 5 demek ax=5 anlamına gelir.
int (interrupt) komutu. İşlemleri yap anlamına gelir. Kendisine parametre olarak girilen kesme hizmetini devreye sokar örneğin INT 21 h
Şimdide bu h ne anlama geliyor.
b ? binary (2’lik sistem)
o ? octal (8’lik sistem) {hemen hemen hiç karşılaşmazsınız}
d ? decimal (10’luk sistem) {bizim kullandığımız}
h ? hexadecimal (16’lık sistem)
Eğer bunları hatırlamadıysanız tekrar sayısal elektronik ve mantık hesaplarını okuyun.
Kırmızı renkler : AX, BX, CX, DX (kaydediciler)
İşlem yapmak için kullandığımız bu kaydediciler parametre (dönüş kodları da bir nevi ters dönen parametredir) için kullanılanlarıdır. Şimdilik bunları değişken olarak görün.
3.2. Genel Amaçlı Kaydediciler (General Purpose Register)
3.2.1. AX, BX, CX, DX
Kaydediciler
Parametre işlemleri için kullanılan bu değişkenlere kaydedici denir. İsimleri sabittir. Kısaltmaları kullanılır.
AX ? accumulator
BX ? base
CX ? counter
DX ? data
Bu kaydediciler (register’lar) 16 bittir. (16 bit 2 byte yapar). Fakat ilginç bir kullanımları daha vardır. Bunları 1 byte şeklinde de kullanmanızı izin verilmiştir. Bunun için şöyle bölmüşlerdir. İlk 8 bit (ilk byte) ve son 8 bit (son byte) olarak. Yani
AX (2 byte) ? AH (ilk byte) ? AL (son byte)
BX (2 byte) ? BH (ilk byte) ? BL (son byte) - (1 byte=8 bit)
CX (16 bit) ? CH (ilk 8 bit) ? CL (son 8 bit)
DX (16 bit) ? DH (ilk 8 bit) ? DL (son 8 bit)
Fark ettiyseniz H’ler ilk kısım (HIGH yüksek demek). L’ler son kısım (LOW düşük demek). (Bazı kaynaklarda AX’in düşük kısmı diye geçebilir şaşırmanıza gerek yok çünkü AL’yi kastediyorlardır)
Ayrıca 80386’dan sonra olması lazım (tam bilmiyorum) bu kaydedicilere yeni olarak EAX, EBX, ECX, EDX gibi yeni bir harf eklendi E ? harfi bu harf sanırım EXTRA anlamına geliyor. EAX olarak ta 32 bit (4 byte) kaydedici şeklinde kullanabiliyorsunuz kaydedicileri. Böyle oluncada AX ise EAX’in düşük kısmı oluyor.
Bu öğrendiklerimizi pekiştirelim.
MOV EAX, AABBCCDD h ? EAX=AABBCCDD (hexadecimal)
Öyleyse
AX = CCDD h
AH = CC h
AL = DD h
Bu örnek olayı anlamanıza yardımcı olmuştur ve güzel bir şey daha var hexadecimal sayılar bu iş için tam kullanımlık.
Tabii kaydedicilerin hepsi 4 tane değil (AX, BX, CX, DX). Bunlar haricinde birçok değişik görevli kaydedici var. En başında belirttiğim gibi bunlar parametre için en çok kullanılanları.
3.2.2. DS, DS, SS, ES
SEGMENT REGISTER
8086 ve 8088 işlemcisi kullanan bilgisayarlar programları ve dataları belleğin iki ayrı alanına yerleştirirler. Bu program ve data alanları max. 64 KB* büyüklüğünde olup Segment olarak isimlendirilir. 8086 ve 8088 işlemcisi aynı anda 4 segmente (Code, Data, Stack, Extra) sahip olabilir. Segmentin başlangıç adresinin gösterilmesi için sırasıyla CS, DS, SS ve ES segment regsiter’ları kullanılır. 220=1 MB* bellek adresleme yeteneğine sahip mikro işlemcide segment register’lar kullanılmak suretiyle 64 KB*’dan daha fazla bir alanın kullanılması sağlanır. Genel olarak 4 tür segment vardır.
* KB, MB gibi kavramları küçük harfle yazarsanız kilobit megabit olur. Burada ise KiloByte MegaByte anlamına geliyor. (kb<>KB & mb <> MB)
CODE SEGMENT
Bu segment çalışan programı içeren segmentin adresini gösterir. Diğer bir deyişle CS ile adreslenen segment içinde makine dili komutları yer almaktadır. Segmentin ilk baytından itibaren program parçası çalıştırılmaya başlanır.
DATA SEGMENT
Data segmenti register’i olan DS geçerli data segmentinin başlangıç adresini içerir. Bu segment genel olarak program değişkenlerini tarafından kullanılır. Diğer bir deyişle bilgi işlem operasyonlarında tabii tutulan bilgiler Data Segment içindeki lokasyonlara (bölümlerde) yer alır.
STACK SEGMENT
Bu segment alt programlara giderken dönüş adreslerini saklamak program bitiminde işletim sistemine dönmek için gerekli bölgelerin saklanmasında kullanılır.
EXTRA SEGMENT
Genel olarak string operasyonları için kullanılır.
BELLEK, SEGMENT VE OFFSET
D.......H
00.....00000
16.....00010
32.....00020
48.....00030
64.....00040
80.....00050 ? dikkat ettiyseniz hepsinin son rakamı 0. (son oktet)
16’nın katları olan tüm hexadecimal sayılarda son rakam (son dijit) daima sıfırdır. Bu özellikten faydalanarak 20 bit uzunluğunda sayıların 16 bit ile adresleyebiliriz. Maksimum 64 KB’dan meydana gelen bölüm segment olarak isimlendirilir. Segmentler yani 64 KB büyüklüğündeki bellek blokları belleğin 16 ile tam olarak bölünebilen herhangi bir lokasyonundan (konumundan) itibaren başlar bir segmentim maksimum genişliği 65536 byte olduğuna göre segment içindeki her bir nokta 16 bit uzunluğundaki sayılar ile adreslenebilir. Bir segment içinde yer alan bir bellek bölgesinin adresini gösteren 16 bir uzunluğundaki işaretsiz tam sayıya offset denilir. Offset adreslerinin içinde bulunan segmentin sıfırıncı byte’ını başlangıç pozisyonu olmaktadır. Yani segment içindeki her bir byte offset dediğimiz adres ile belirlenir.
SEGMENT
Gerçek adresi bulmak için 16 h ile çarpılır (bu hexadecimal bir sayının sağına sıfır eklemekle aynı şeylerdir). Böylelikle 64 KB’dan büyük hafızalar sanki 64 KB gibi kullanılabilir.
Belirli segment register’ları için belirli offset register’ları kullanılır.
Segment Offset
CS IP
SS SP, BP
DS BX, SI, DI veya sabit
ES DI (string işlemlerde)
3.2.3. SP, BP, SI, DI, IP
IP ve BX register’larında birer pointer ya da index register’ı olarak kabul etmek mümkündür. Bu register’ların kullanımındaki asıl amaç segmentler içerisindeki offset adresini göstermek için kullanılır.
SP : Source Index
String işlemlerde DS ile birlikte kullanılır.
DS : Destination Index
Bazı string işlemlerinde DS ile birlikte kullanılır.
SP : Stack Pointer
Stack segment’teki geçici stack alanlarını işaretlemek için kullanılır.
BP : Base Pointer
Stack segment’teki geçici stack alanlarını işaretlemek için kullanılır.
IP : Instruction Pointer
Komut göstergesi olan IP, CS içinde çalıştırılacak komutun offset adresini gösterir.
3.2.4. Program Status Word (Flag Register)
Bu register komut çalışması sonunda oluşan durumu test etmek için kullanılır.
PWS (Program Word Status) {Durum Kaydediciler}
Parametrelerden bahsetmiştik şimdide onlara yardımcı olan bir araçtan bahsedeceğim. Durum-Kaydedici(PWS) register-(kaydedici)’de yapılan bir işlemden sonra buradaki bayraklar (flag’lar) durumu bildirir.
Bazı bayraklar.
Z ? zero flag : sıfır bayrağı (ya da sıfır biti)
S ? sign flag : işaret bayrağı
O ? overflow flag : taşma bayrağı
I ? interrupt flag : kesme bayrağı
C ? carry flag : elde bayrağı
T ? trap flag : adımlama bayrağı
Flag (bayrak) nedir ?
Flag’lar tek bitlik kayıtçılardır. Yani sadece 1 veya 0 gösterebilir. Flag 0 durumunu gösteriyorsa buna FALSE (reset), eğer 1 durumunu gösteriyorsa buna TRUE (set) denir. (Türkçe var yok gibi kelimelere çevirebilir)
Bayraklar ve Durumlarının Etkilenmesi
Zero Flag
Aritmetik ve karşılaştırma işlemlerinde sonuç 0 ise Z=SET olur. Aksi taktire RESET olarak bekler.
(1=SET= TRUE)
Sign Flag
Aritmetik işlemlerde sonuç pozitif ise S=SET olur.
Interrupt Flag
Kesme maskesi olarak kullanılır. I=1 ise kesme girişinde kesme kabul edilmez.
Carry Flag
Aritmetik işlemler sonucunda oluşan elde bitini depolar. Ayrıca ROTATE ve SHIFT işlemlerinde son biti depolar.
Overflow Flag
İşaretli sayılar üzerinde işlem yapılırken işaret biti üzerinde bir taşma olursa bu bayrak SET edilir.
*İşaretli Sayılar : Sayılar çift yönlüdür yani negatif ve pozitif kısımları vardır. Örneğin 65536 sayısı pozitif tam sayı olarak tanımlarsak 16 bit eder. Fakat biz bu sayının eksi işaretlisini de kullanmak istersek 1 biti eksi işareti göstersin diye ayırıyoruz. O zamanda sayı için kullanabileceğimiz alan 15 bit’e düşüyor. 0 sayısıda pozitif olanlara dahil olduğu için pozitif sayılar negatif sayılarınkinden 1 ek* Yasak Kelime Kullandınız *. Hepsini örnekleyelim
16 Bit sayı (tek duyarlı)
11111111.11111111 = 65536
16 Bit işaretli sayı (çift duyarlı)
1 1111111.11111111 = 32767
0 1111111.11111111 =-32768
İşaretsiz Sayılar : Sadece pozitif sayılardır. 0’dan +(artı) sonsuza kadar olabilir.
3.3. Genel Komutlar
3.3.1. MOV komutu
Etkilenen bayraklar: [yok]
Genel Yazım Formları
mem : memory (hafıza bölgesi)
reg : register (kaydedici)
MOV reg, mem
MOV mem, reg
MOV mem, mem
MOV reg, reg
MOV (move) komutu. Buradaki görevi eşittir işareti gibi düşünebilirsiniz. Yani MOV AX, 5 demek ax=5 anlamına gelir.
3.3.1. INC (increment)
Etkilenen bayraklar: [AF OF PF SF ZF]
INC reg
INC mem
Parametre girilen bilgiyi bir sayı artırır.
MOV AX, 0
INC AX
AX=1 olacaktır.
3.3.2. DEC (decrement)
Etkilenen bayraklar: [AF OF PF SF ZF]
DEC reg
DEC mem
Parametre girilen bilgiyi bir sayı eksiltir.
MOV BX, 9
DEC BX
BX=8 olacaktır.
3.3.3. INT (interrupt)
Etkilenen bayraklar: [TF IF]
***under const.***
3.3.4. CMP (compare)
Etkilenen bayraklar: [AF CF OF PF SF ZF]
CMP reg, reg
CMP reg, mem
CMP mem, reg
CMP mem, immed
Karşılaştırma Komutudur. İki bilginin birbiriyle karşılaştırması için kullanılır. Karşılaştırma işlemi 3 basamakta yapılır.
a. İlk parametre bilgisi ikinci parametre bilgisinden çıkartılır.
b. Çıkan sonuç Durum Bayrağını (PWS) değiştirir.
c. Kendinden sonra gelen satır için Durum Bayrağını ayarlamıştır.
Bu kısmı biraz açıklamak istiyorum. Örneği inceliyelim
MOV AX,15h
MOV BX,15h
CMP AX, BX
Sizden buradaki CMP’yi ADD gibi düşünmenizi istiyorum. Fakat AX’in değerinin değişmediğini düşünün çünkü biz Durum Bayrağıyla ilgileniyoruz.... Böyle bir durumda bizim etkilenen bayraklarımız olacak örneğin ZF, CF, OF, SF gibi. Eğer biz AX’ten BX’i çıkartırsak ne olur. İlk olarak biz sayıların eşitliğini bulalım 15 - 15 = 0 ise ZF = SET olur. Diğer bayraklar RESET’ler (ki bizim şu an onlarla işimiz yok). Yani şöyle bağlıyayım, çıkartma işleminin sonucunun 0 olması için sayıların aynı olmasının gerektiğini biliyoruz. Öyleyse ZF = TRUE ise demektir ki sayılarımız eşit. Şimdi aşağıda bayrakları da verdiğim Jump koşullarına bakabilirsiniz.
3.3.5. JUMP .............
Genel Yazım Formatı
Jxxx* label
Koşul uyuşuyorsa label adresine git. Jump komutları bu iş için bayraklardan faydalanırlar aşağıda size bunun dökümünü veriyorum.
Opr.1 ve Opr.2 Opr.1 ve Opr.2 Araştırılan
İşaretsiz ise İşaretli ise koşul
JZ, JE JZ, JE Opr1 = Opr2
JR, JC, JNAE JL, JNGE Opr1 < Opr2
JA, JNBE JG, JNLE Opr1 > Opr2
JB, JNA JLE, JNG Opr1 <= Opr2
JNB, JNC, JAE JGE, JNL Opr1 >= Opr2
JNZ, JNE JNZ, JNE Opr1 <> Opr2
Komut Komuntun tam ismi İşlevi İstenen koşul
*JE Jump if Equal Eşitse ZF=1
*JNE Jump if Not Equal Eşit değilse ZF=0
JB Jump if Below Küçükse CF=1
JNB Jump if Not Below Küçük değilse CF=0
JA Jump if Above Büyükse CF=0 and ZF=0
JNA Jump if Not Above Büyük değilse CF=1 or ZF=1
JBE Jump if Below or Equal Küçük veya eşitse CF=1 or ZF=1
JAE Jump if Above or Equal Büyük veya eşitse CF=0
JNBE Jump if Not Below nor Equal Küçük değil ve eşit değilse CF=0 and ZF=0
JNAE Jump if Not Above nor Equal Büyük değil ve eşit değilse CF=1
*JZ Jump if Zero Sıfırsa ZF=1
*JNZ Jump if Not Zero Sıfır değilse ZF=0
JC Jump if Carry Taşma varsa CF=1
JNC Jump if Not Carry Taşma yoksa CF=0
JP Jump if Parity Bitler çift sayıda ise PF=1
JPE Jump if Parity Even Bitler çift sayıda ise PF=1
JNP Jump if Not Parity Bitler çift sayıda değilse PF=0
JPO Jump if Parity Odd Bitler tek sayıda ise PF=0
JCXZ Jump if CX is Zero CX’in değeri sıfır ise CX=0000
-JL Jump if Less Küçükse SF<>0F
-JNL Jump if Not Less Küçük değilse SF=0F
-JG Jump if Greater Büyükse ZF=0 and SF=0F
-JNG Jump if Not Greater Büyük değilse ZF=1 or SF<>0F
-JLE Jump if Less or equal Küçük veya eşitse ZF=1 or SF<>0F
-JGE Jump if Greater or Equal Büyük veya eşitse SF=0F
-JNLE Jump if Not Less nor Equal Küçük değil ve eşit değilse ZF=0 and SF=0F
-JNGE Jump if Not Greater nor Equal Büyük değil ve eşit değilse SF<>0F
-JO Jump if Overflow Taşma varsa OF=1
-JNO Jump if Not Overflow Taşma yoksa OF=0
-JS Jump if Sign Negatif ise SF=1
-JNS Jump if Not Sign Pozitif ise SF=0
*:İşaretli sayılar üzerinde yapılan operasyonlardan sonra kullanılır
-:hem işaretli hemde işaretsiz sayılar üzerinde yapılan operasyonlardan sonra kullanılır.
:* ve - işaretli olan komutlar işaretsiz sayılar üzerinde yapılan operasyonlardan sonra kullanılır.
3.3.6. ADD, MUL, DIV
Etkilenen bayraklar: [AF CF OF PF SF ZF]
Genel Yazım Formatı
ADD kaynak, hedef
ADD reg, reg
ADD reg, mem
ADD mem, reg
ADD mem, immed
Yapılan işlem sonrası gösterilen hedef, kaynağa eklenir. Örneğin;
MOV AX, 5
MOV BX, 3
ADD AX, BX
İşleminden sonra
AX=8
BX=3 olacaktır.
Çıkartma işlemi içinde aynı sırayı takip edebilirsiniz. Çıkartma, çarpma ve bölme aslında bir tür seri toplama işlemidir. Yani çıkartma işlemi içinde ADD kullanıyoruz. Örneğin 8’den 3’ü çıkartalım.
MOV AX, 8
ADD AX, -3
AX=5 olmuştur.
MUL (multiply)
Etkilenen bayraklar: [CF OF], [AF,PF,SF,ZF belirsiz]
MUL reg
MUL mem
IMUL
Bu kısımları özet olarak geçiyorum. MUL ile işaretsiz sayıları çarpabilirsiniz IMUL ilede işaretli sayıları çarpabilirsiniz.
Etkilenen bayraklar: [AF,CF,OF,PF,SF,ZF belirsiz]
DIV reg
DIV mem
IDIV
DIV (divide)
DIV ile işaretsiz sayıları IDIV ilede işaretli sayıları bölebilirsiniz.
3.3.7. Bazı komutlar (biraz bildiğini varsayanlar baksın)
CALL - RET
Bir tür prosedür gibi düşünebilirsiniz. Programı bu şekilde bölütlere ayırarak daha etkin kullanabilirsiniz. Bir CALL içine girildikten sonra RET komutu görülünceye kadar ilerlenir. (BASIC dilindeki gosub ve return komutu gibi;-)
PUSH - POP
PUSH, POP : genel amaçlı yığıtçılar
PUSHA, POPA : EDI, ESI, EBP, ESP, EDX, ECX, EAX sakla
PUSHF, POPF : bayrakların durumunu yığıtla
Kaydedici, Hafıza veya Durum Bayraklarını saklamanızı sağlar.
Şöyle düşünelim kullandığımız değişkenler çok sınırlı bir miktarda bunları bir şekilde bir yerlerde de saklamamız gerekli işte bunun için hafızada yığıt (stack) yaparız. Siz her saklama işlemi yaptığınızda hafızaya bir bilgi eklenir. {her yeni bilgi SS:SP’nin üstüne atılır.}
Daha sonra sakladığınız bilgileri geri çağırmak için POP’u kullanırız.
LOOP
Genel Yazım Formu : LOOP label
Genel amaçlı sayıcıdır. CX’ 0 olana kadar LABEL’a sürekli döner durur.
0100: MOV DX, 0
0103: MOV CX, 5
0106: ADD DX, CX
0108: LOOP 0106
program bitiminde dönen değerler böyle olur.
CX = 0 h
DX = F h
(for döngülerine benzetebilirsiniz)
3.4. Prototip Program ve Op Code için örnekler
***YORULDUM 10 SAAT OLDU ARTIK DİNLENİYİM ?***
ayrıca bana ulaşmak isterseniz. e-mail adresim altta.
Demiş miydim bilmiyorum ama kaynak göstererek de olsa iznim olmadan yayınlayamazsınız diye ???
Yazının başında da bahsettiğim gibi programlama dili seviyeleri yüksek ve düşük seviye olmak üzere ikiye ayrılır. Yüksek seviye programlama dilleri bizlerin daha basit kullandığı bir arayüze (InterFace) sahiplerdir. En yüksek seviye programlama dili bile bilgisayar tarafından anlaşılması için düşük seviye dile çevrilir. Yani siz hangi platformda programlama yaparsanız yapın bilgisayar bunu kendi anlayacağı dile çevirip işler. Buda assembly’dir. Assembly diğer dillere nazaran anlaşılması bir karmaşayı öğrenmeye benzer. Çünkü işlemler en basit mantık adımlarının bütünleşmesiyle oluşur.
Bu bütünün yapısını incelersek karşımıza kavramlar çıkar. Hafıza ve İşlemci tüm işlemlerin yürütüldüğü ve oluşumlar için ortam sağlayan kısımdır. Assembly düşük seviye bir dil olduğu için işlemlerde en basit adımlarla sırayla gerçekleşir. İşlemci ve Hafıza gerekli bilgiyi işledikten sonra bunları kullanması için çeşitli şekillerde dağıtacaktır. Ama biz bunun dağıtılması ve toplanmasını değil sadece işleyiş biçimini inceleyeceğiz.
Hafıza (Memory)
Bir defter gibi düşünebilirsiniz. Bilgi tutmaya yarayan bir araçtır. Elde edilen bilgiler, yapılacak işlemler, işlemlerin sonuçları vb. tüm bilgiler bu sayfalara yazılacaktır.
İşlemci (Processor)
Hafızadaki (defterdeki) tüm bilgileri okuyacak bunları değerlendirecek ve değerlendirme sonuçlarını tekrar deftere yazabilecektir hatta bu işlemler, başka birimleri ilgilendiriyorsa onlarla da iletişime geçecek ve onlarda da gerekli iletişim ve işlemleri yapacaktır.
Bir programın çalışması
Bir işlemcinin işleri en basit adımlarla sırayla yaptığını hatırlayalım. Onun için bizde bir programın çalışmasını sizlere
ÖZEL BAZI BİLGİLER
*Kaydediciler bir hafıza bölümü olması rağmen hafızanın içinde değil işlemcinin içinde yer alırlar.
Bunun iki ana sebebi vardır ilk olarak işlemci hafızaya göre çok üstün bir hızda çalışır. İkinci olarak ta işlemci bu bilgileri çok kullandığı için yolunu uzatmamış olur.
*Bir işlemci aynı anda sadece 1 iş yapabilir. Çünkü uyulması gereken sıra vardır fakat birbirini etkilemeyen komutlar artarda gelirlerse bunları birbirinden bağımsız olarak işleyip hız kazanabilir. Bu yeni nesil işlemcilerde karşılaştırma işlemlerinde dahi kullanılmaktadır. Böylece yavaş artan frekans yerine işlemlerin süresinden kazanç elde edilir.
Ama önce bunlar lazım
1. Bilgisayarınız olsun ?
2. İçinde Windows ve DOS, bunlar içinde programlama dilleri olsun
3. matematiğiniz olsun ve mantık hesaplarını biliniz
4. elektronik bilginiz olsun (sayısal elektroniğinizde)
5. İngilizce’niz olsun
6. biraz çalışan beyin
Bir bilgisayarınız olmalı elbette
Bu işi yapmak için elinizde bulunacak eski bir 8086 bilgisayar yeterli olur. Şimdi soracaksınız benim bilgisayarım olur mu diye. Olur, çünkü bu işlemci temelli olması yeterli bilgisayarınızın ki şu an çıkan Pentium 4’ler bile bu temeli kullanır.
Şimdi asıl içeriğimize geçelim. Eğer temeliniz yoksa bu yazıyı okumanın sadece kafanızı karıştıracağını düşünüyorum.
INDEKS
1. Programlama Dilleri
2. Sayısal Elektronik ve Mantık Hesaplamaları
3. Assembly’e Giriş
3.1. Hafıza ve İşlemci (RAM & CPU)
3.2. Genel Amaçlı Kaydediciler (General Purpose Register)
3.2.1. AX, BX, CX, DX
3.2.2. DS, DS, SS, ES
3.2.3. SP, BP, SI, DI, IP
3.2.4. Program Status Word (Flag Register)
3.3. Genel Komutlar
3.3.1. MOV
3.3.2. INC
3.3.3. DEC
3.3.4. INT
3.3.5. CMP
3.3.6. JUMP .............
3.3.7. CALL – RET
3.4. Prototip Program ve Op Code için örnekler
1. Programlama Dilleri
Bilgisayarınıza işlem yaptırabilmek için ona birbiriyle bağıntılı toplu emirler vermeniz gerekir. Örnek verirsem. Susadın mı ? evet veya hayır olarak iki cevap gelir. Evet ise su iç hayırsa işlem yapma. Bu olay bilgisayar ile aranızda ortak bir dil kurulmasının gerektirir. Bu dil hanginize daha yakınsa diğeri daha çok zorlanır. Bir bilgisayarın anlayacağı en iyi dil makine dilidir. Bu dilde komutlar ve tanımlar yerini bilgi şekline dönüştürür. Yukarıdaki örneği makine dili için şöyle yaparız. Musluğu aç bardağı musluğun altına tut dolunca bardağı çek ve musluğu kapat. İşte bu ayrımdan dolayı dil seviyeleri ortaya çıkar.
2. Sayısal Elektronik ve Mantık Hesaplamaları
Hepimizin bildiği modern matematikte 10’luk sayı sistemini kullanırız. Fakat bizim kullandığımız sayı sistemi haricinde bilmemiz gereken 3 adet sayı sistemi daha var. İlk olarak kendi kullandığımız sistemi inceleyelim.
0, 1, 2, 3, 4, 5, 6, 7, 8, 9 : Bizim kullandığımız sayı sisteminde 10 rakam vardır. Bu sistemin adı 10’luk taban ya da Decimal sayı sistemi olarak bilinir.
Şimdi diğerlerine bakalım
0, 1 : Binary (2’lik) sayı sistemi
0, 1, 2, 3, 4, 5, 6, 7 : Octal (8’lik) sayı sistemi
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F : Hexadecimal (16’lık) sayı sistemi
Aslında tüm sistemler aynı sayılır. Sadece kullanım biçimi olarak değişiklik gösterir. Şuna açıklık getiriyim bu sayı sistemleri birbirlerine dönüşebilirler. Genelde şu vardır BINARY sayı sistemi ile 1’den büyük rakamlar nasıl yazılıyor. Yazılır ? bunu maalesef burada anlatamayacağım. Ama tekrar söylüyorum tüm sayı sistemleri ile modern matematikte kullandığımız işlemleri yapabilirsiniz.
Sorumuzun cevabı : Bu sistemleri bilgisayar kullanır. Bilgisayar tüm bilgileri BINARY (2’lik sayı tabanı) olarak alır. Bunlar HEXADECIMAL kalıplar biçimli kullanılır. Örneğin veriyi byte’ler şeklinde okur fakat kendi iletişim trafiği içinde bunu muhakkak BINARY sisteme çevirir.
3. Assembly’e Giriş
3.1. Hafıza ve İşlemci (RAM & CPU)
Hafıza (Random Access Memory) (Rasgele Erişimli Bellek)
Üzerinde çalışılan bir masa gibi düşünebiliriz. İşlemlerimiz için bu bölgeyi kullanılırız.
İşlemci (Central Proccess Unit) (Merkezi İşlem Birimi)
İşlemlerimizi yaptırdığımız yer bu kısımdır.
Çalışmaları
Hadi artık başlayalım;
Bir işlem yaptırmak nasıl oluyor bununla başlayalım. Şimdi bu karmaşık konuyu kafanızda canlandırabilmeniz için örnekler veriyorum.
Bir bilgiyi ekrana yazdıralım.
Öncelikle bu iş için hafızada bir bilgi olduğunu varsayalım. İşlemcimize şunu demeliyiz hafızanın şu bölgesindeki bilgiyi tut ve ekranın şu kısmına yaz.
Bir bilgiyi okutalım.
(bunu da otomatik yapabiliyor ama biz incelediğimiz için teorikleştiriyoruz)
İşlemcimiz klavyeden gelen her bilgiyi okusun. Sonra bunu hafızaya yerleştirsin ve ekranda da belirtsin.
Tabii yapabileceklerimiz bununla sınırlı değil işlemcimiz ile tüm donanımlara ait kontrolleri gelişmiş şekilde denetleyip, yönetebiliyoruz. Şimdi yukarıdaki iki örneğe tekrar dönelim dikkatinizi çekti mi bilmiyorum ama anlatayım. Biz önce bilgisayara hazır veriyi işlettik ikinci örnekteyse bilgisayardan bilgi alıp daha sonra bunu yazdırttık yani biz işlemciye hem bilgilerimizi işlettirebiliyoruz hem de işlemciden istediğimiz bir bilgiyi alabiliyoruz. Ya da bir işlem içinde ikisini de gerçekleştirebiliyoruz. Biz buna kesme isteği diyoruz.
IRQ (Interrupt Request) {Kesme İsteği}
Bilgisayara işlem yaptırırken bunu Kesme İstekleri ile yapıyoruz. Yine örnekliyorum; Aşağıda bilgisayarın tarihini değiştiriyoruz.
X değeri = 15 (ayın günü)
Y değeri = 3 (ay)
Z değeri = 2001 (yıl)
Kesme İsteği Kodu
İlgili Kesmeyi Yap
Gördüğünüz gibi örnekte bilgisayara parametre verip bunları işlemesini istedik şimdide biz bilgisayardan veri alalım.
Kesme İsteği Kodu
İlgili Kesmeyi Yap
X değeri = gün (yani X günü gösteriyor)
Y değeri = ay (Y ayı gösteriyor)
Z değeri = yıl (Z yılı gösteriyor)
Şimdide bilgisayardan kesme ile return code (dönüş kodları) elde ettik.
Örneklerden de anlaşılabileceği gibi kesme ile işlemlerimizi yaptırabiliyoruz. Yukarıda gördüğünüz örnekleri makine diline çevirelim ve bu bilgileri tekrar incelemeye koyulalım.
mov DL, bugun
mov DH, ay
mov CX, sene
mov AH, 2B h
int 21 h
mov AH, 2A h
int 21 h
mov gun, AL h
mov ay, DH h
mov sene, CX h
Yukarıdaki renklerin ne olduğunu hemen açıklayayım.
Mavi renkler : mov ve int komutu
mov (move) komutu. Buradaki görevi eşittir işareti gibi düşünebilirsiniz. Yani MOV AX, 5 demek ax=5 anlamına gelir.
int (interrupt) komutu. İşlemleri yap anlamına gelir. Kendisine parametre olarak girilen kesme hizmetini devreye sokar örneğin INT 21 h
Şimdide bu h ne anlama geliyor.
b ? binary (2’lik sistem)
o ? octal (8’lik sistem) {hemen hemen hiç karşılaşmazsınız}
d ? decimal (10’luk sistem) {bizim kullandığımız}
h ? hexadecimal (16’lık sistem)
Eğer bunları hatırlamadıysanız tekrar sayısal elektronik ve mantık hesaplarını okuyun.
Kırmızı renkler : AX, BX, CX, DX (kaydediciler)
İşlem yapmak için kullandığımız bu kaydediciler parametre (dönüş kodları da bir nevi ters dönen parametredir) için kullanılanlarıdır. Şimdilik bunları değişken olarak görün.
3.2. Genel Amaçlı Kaydediciler (General Purpose Register)
3.2.1. AX, BX, CX, DX
Kaydediciler
Parametre işlemleri için kullanılan bu değişkenlere kaydedici denir. İsimleri sabittir. Kısaltmaları kullanılır.
AX ? accumulator
BX ? base
CX ? counter
DX ? data
Bu kaydediciler (register’lar) 16 bittir. (16 bit 2 byte yapar). Fakat ilginç bir kullanımları daha vardır. Bunları 1 byte şeklinde de kullanmanızı izin verilmiştir. Bunun için şöyle bölmüşlerdir. İlk 8 bit (ilk byte) ve son 8 bit (son byte) olarak. Yani
AX (2 byte) ? AH (ilk byte) ? AL (son byte)
BX (2 byte) ? BH (ilk byte) ? BL (son byte) - (1 byte=8 bit)
CX (16 bit) ? CH (ilk 8 bit) ? CL (son 8 bit)
DX (16 bit) ? DH (ilk 8 bit) ? DL (son 8 bit)
Fark ettiyseniz H’ler ilk kısım (HIGH yüksek demek). L’ler son kısım (LOW düşük demek). (Bazı kaynaklarda AX’in düşük kısmı diye geçebilir şaşırmanıza gerek yok çünkü AL’yi kastediyorlardır)
Ayrıca 80386’dan sonra olması lazım (tam bilmiyorum) bu kaydedicilere yeni olarak EAX, EBX, ECX, EDX gibi yeni bir harf eklendi E ? harfi bu harf sanırım EXTRA anlamına geliyor. EAX olarak ta 32 bit (4 byte) kaydedici şeklinde kullanabiliyorsunuz kaydedicileri. Böyle oluncada AX ise EAX’in düşük kısmı oluyor.
Bu öğrendiklerimizi pekiştirelim.
MOV EAX, AABBCCDD h ? EAX=AABBCCDD (hexadecimal)
Öyleyse
AX = CCDD h
AH = CC h
AL = DD h
Bu örnek olayı anlamanıza yardımcı olmuştur ve güzel bir şey daha var hexadecimal sayılar bu iş için tam kullanımlık.
Tabii kaydedicilerin hepsi 4 tane değil (AX, BX, CX, DX). Bunlar haricinde birçok değişik görevli kaydedici var. En başında belirttiğim gibi bunlar parametre için en çok kullanılanları.
3.2.2. DS, DS, SS, ES
SEGMENT REGISTER
8086 ve 8088 işlemcisi kullanan bilgisayarlar programları ve dataları belleğin iki ayrı alanına yerleştirirler. Bu program ve data alanları max. 64 KB* büyüklüğünde olup Segment olarak isimlendirilir. 8086 ve 8088 işlemcisi aynı anda 4 segmente (Code, Data, Stack, Extra) sahip olabilir. Segmentin başlangıç adresinin gösterilmesi için sırasıyla CS, DS, SS ve ES segment regsiter’ları kullanılır. 220=1 MB* bellek adresleme yeteneğine sahip mikro işlemcide segment register’lar kullanılmak suretiyle 64 KB*’dan daha fazla bir alanın kullanılması sağlanır. Genel olarak 4 tür segment vardır.
* KB, MB gibi kavramları küçük harfle yazarsanız kilobit megabit olur. Burada ise KiloByte MegaByte anlamına geliyor. (kb<>KB & mb <> MB)
CODE SEGMENT
Bu segment çalışan programı içeren segmentin adresini gösterir. Diğer bir deyişle CS ile adreslenen segment içinde makine dili komutları yer almaktadır. Segmentin ilk baytından itibaren program parçası çalıştırılmaya başlanır.
DATA SEGMENT
Data segmenti register’i olan DS geçerli data segmentinin başlangıç adresini içerir. Bu segment genel olarak program değişkenlerini tarafından kullanılır. Diğer bir deyişle bilgi işlem operasyonlarında tabii tutulan bilgiler Data Segment içindeki lokasyonlara (bölümlerde) yer alır.
STACK SEGMENT
Bu segment alt programlara giderken dönüş adreslerini saklamak program bitiminde işletim sistemine dönmek için gerekli bölgelerin saklanmasında kullanılır.
EXTRA SEGMENT
Genel olarak string operasyonları için kullanılır.
BELLEK, SEGMENT VE OFFSET
D.......H
00.....00000
16.....00010
32.....00020
48.....00030
64.....00040
80.....00050 ? dikkat ettiyseniz hepsinin son rakamı 0. (son oktet)
16’nın katları olan tüm hexadecimal sayılarda son rakam (son dijit) daima sıfırdır. Bu özellikten faydalanarak 20 bit uzunluğunda sayıların 16 bit ile adresleyebiliriz. Maksimum 64 KB’dan meydana gelen bölüm segment olarak isimlendirilir. Segmentler yani 64 KB büyüklüğündeki bellek blokları belleğin 16 ile tam olarak bölünebilen herhangi bir lokasyonundan (konumundan) itibaren başlar bir segmentim maksimum genişliği 65536 byte olduğuna göre segment içindeki her bir nokta 16 bit uzunluğundaki sayılar ile adreslenebilir. Bir segment içinde yer alan bir bellek bölgesinin adresini gösteren 16 bir uzunluğundaki işaretsiz tam sayıya offset denilir. Offset adreslerinin içinde bulunan segmentin sıfırıncı byte’ını başlangıç pozisyonu olmaktadır. Yani segment içindeki her bir byte offset dediğimiz adres ile belirlenir.
SEGMENT
Gerçek adresi bulmak için 16 h ile çarpılır (bu hexadecimal bir sayının sağına sıfır eklemekle aynı şeylerdir). Böylelikle 64 KB’dan büyük hafızalar sanki 64 KB gibi kullanılabilir.
Belirli segment register’ları için belirli offset register’ları kullanılır.
Segment Offset
CS IP
SS SP, BP
DS BX, SI, DI veya sabit
ES DI (string işlemlerde)
3.2.3. SP, BP, SI, DI, IP
IP ve BX register’larında birer pointer ya da index register’ı olarak kabul etmek mümkündür. Bu register’ların kullanımındaki asıl amaç segmentler içerisindeki offset adresini göstermek için kullanılır.
SP : Source Index
String işlemlerde DS ile birlikte kullanılır.
DS : Destination Index
Bazı string işlemlerinde DS ile birlikte kullanılır.
SP : Stack Pointer
Stack segment’teki geçici stack alanlarını işaretlemek için kullanılır.
BP : Base Pointer
Stack segment’teki geçici stack alanlarını işaretlemek için kullanılır.
IP : Instruction Pointer
Komut göstergesi olan IP, CS içinde çalıştırılacak komutun offset adresini gösterir.
3.2.4. Program Status Word (Flag Register)
Bu register komut çalışması sonunda oluşan durumu test etmek için kullanılır.
PWS (Program Word Status) {Durum Kaydediciler}
Parametrelerden bahsetmiştik şimdide onlara yardımcı olan bir araçtan bahsedeceğim. Durum-Kaydedici(PWS) register-(kaydedici)’de yapılan bir işlemden sonra buradaki bayraklar (flag’lar) durumu bildirir.
Bazı bayraklar.
Z ? zero flag : sıfır bayrağı (ya da sıfır biti)
S ? sign flag : işaret bayrağı
O ? overflow flag : taşma bayrağı
I ? interrupt flag : kesme bayrağı
C ? carry flag : elde bayrağı
T ? trap flag : adımlama bayrağı
Flag (bayrak) nedir ?
Flag’lar tek bitlik kayıtçılardır. Yani sadece 1 veya 0 gösterebilir. Flag 0 durumunu gösteriyorsa buna FALSE (reset), eğer 1 durumunu gösteriyorsa buna TRUE (set) denir. (Türkçe var yok gibi kelimelere çevirebilir)
Bayraklar ve Durumlarının Etkilenmesi
Zero Flag
Aritmetik ve karşılaştırma işlemlerinde sonuç 0 ise Z=SET olur. Aksi taktire RESET olarak bekler.
(1=SET= TRUE)
Sign Flag
Aritmetik işlemlerde sonuç pozitif ise S=SET olur.
Interrupt Flag
Kesme maskesi olarak kullanılır. I=1 ise kesme girişinde kesme kabul edilmez.
Carry Flag
Aritmetik işlemler sonucunda oluşan elde bitini depolar. Ayrıca ROTATE ve SHIFT işlemlerinde son biti depolar.
Overflow Flag
İşaretli sayılar üzerinde işlem yapılırken işaret biti üzerinde bir taşma olursa bu bayrak SET edilir.
*İşaretli Sayılar : Sayılar çift yönlüdür yani negatif ve pozitif kısımları vardır. Örneğin 65536 sayısı pozitif tam sayı olarak tanımlarsak 16 bit eder. Fakat biz bu sayının eksi işaretlisini de kullanmak istersek 1 biti eksi işareti göstersin diye ayırıyoruz. O zamanda sayı için kullanabileceğimiz alan 15 bit’e düşüyor. 0 sayısıda pozitif olanlara dahil olduğu için pozitif sayılar negatif sayılarınkinden 1 ek* Yasak Kelime Kullandınız *. Hepsini örnekleyelim
16 Bit sayı (tek duyarlı)
11111111.11111111 = 65536
16 Bit işaretli sayı (çift duyarlı)
1 1111111.11111111 = 32767
0 1111111.11111111 =-32768
İşaretsiz Sayılar : Sadece pozitif sayılardır. 0’dan +(artı) sonsuza kadar olabilir.
3.3. Genel Komutlar
3.3.1. MOV komutu
Etkilenen bayraklar: [yok]
Genel Yazım Formları
mem : memory (hafıza bölgesi)
reg : register (kaydedici)
MOV reg, mem
MOV mem, reg
MOV mem, mem
MOV reg, reg
MOV (move) komutu. Buradaki görevi eşittir işareti gibi düşünebilirsiniz. Yani MOV AX, 5 demek ax=5 anlamına gelir.
3.3.1. INC (increment)
Etkilenen bayraklar: [AF OF PF SF ZF]
INC reg
INC mem
Parametre girilen bilgiyi bir sayı artırır.
MOV AX, 0
INC AX
AX=1 olacaktır.
3.3.2. DEC (decrement)
Etkilenen bayraklar: [AF OF PF SF ZF]
DEC reg
DEC mem
Parametre girilen bilgiyi bir sayı eksiltir.
MOV BX, 9
DEC BX
BX=8 olacaktır.
3.3.3. INT (interrupt)
Etkilenen bayraklar: [TF IF]
***under const.***
3.3.4. CMP (compare)
Etkilenen bayraklar: [AF CF OF PF SF ZF]
CMP reg, reg
CMP reg, mem
CMP mem, reg
CMP mem, immed
Karşılaştırma Komutudur. İki bilginin birbiriyle karşılaştırması için kullanılır. Karşılaştırma işlemi 3 basamakta yapılır.
a. İlk parametre bilgisi ikinci parametre bilgisinden çıkartılır.
b. Çıkan sonuç Durum Bayrağını (PWS) değiştirir.
c. Kendinden sonra gelen satır için Durum Bayrağını ayarlamıştır.
Bu kısmı biraz açıklamak istiyorum. Örneği inceliyelim
MOV AX,15h
MOV BX,15h
CMP AX, BX
Sizden buradaki CMP’yi ADD gibi düşünmenizi istiyorum. Fakat AX’in değerinin değişmediğini düşünün çünkü biz Durum Bayrağıyla ilgileniyoruz.... Böyle bir durumda bizim etkilenen bayraklarımız olacak örneğin ZF, CF, OF, SF gibi. Eğer biz AX’ten BX’i çıkartırsak ne olur. İlk olarak biz sayıların eşitliğini bulalım 15 - 15 = 0 ise ZF = SET olur. Diğer bayraklar RESET’ler (ki bizim şu an onlarla işimiz yok). Yani şöyle bağlıyayım, çıkartma işleminin sonucunun 0 olması için sayıların aynı olmasının gerektiğini biliyoruz. Öyleyse ZF = TRUE ise demektir ki sayılarımız eşit. Şimdi aşağıda bayrakları da verdiğim Jump koşullarına bakabilirsiniz.
3.3.5. JUMP .............
Genel Yazım Formatı
Jxxx* label
Koşul uyuşuyorsa label adresine git. Jump komutları bu iş için bayraklardan faydalanırlar aşağıda size bunun dökümünü veriyorum.
Opr.1 ve Opr.2 Opr.1 ve Opr.2 Araştırılan
İşaretsiz ise İşaretli ise koşul
JZ, JE JZ, JE Opr1 = Opr2
JR, JC, JNAE JL, JNGE Opr1 < Opr2
JA, JNBE JG, JNLE Opr1 > Opr2
JB, JNA JLE, JNG Opr1 <= Opr2
JNB, JNC, JAE JGE, JNL Opr1 >= Opr2
JNZ, JNE JNZ, JNE Opr1 <> Opr2
Komut Komuntun tam ismi İşlevi İstenen koşul
*JE Jump if Equal Eşitse ZF=1
*JNE Jump if Not Equal Eşit değilse ZF=0
JB Jump if Below Küçükse CF=1
JNB Jump if Not Below Küçük değilse CF=0
JA Jump if Above Büyükse CF=0 and ZF=0
JNA Jump if Not Above Büyük değilse CF=1 or ZF=1
JBE Jump if Below or Equal Küçük veya eşitse CF=1 or ZF=1
JAE Jump if Above or Equal Büyük veya eşitse CF=0
JNBE Jump if Not Below nor Equal Küçük değil ve eşit değilse CF=0 and ZF=0
JNAE Jump if Not Above nor Equal Büyük değil ve eşit değilse CF=1
*JZ Jump if Zero Sıfırsa ZF=1
*JNZ Jump if Not Zero Sıfır değilse ZF=0
JC Jump if Carry Taşma varsa CF=1
JNC Jump if Not Carry Taşma yoksa CF=0
JP Jump if Parity Bitler çift sayıda ise PF=1
JPE Jump if Parity Even Bitler çift sayıda ise PF=1
JNP Jump if Not Parity Bitler çift sayıda değilse PF=0
JPO Jump if Parity Odd Bitler tek sayıda ise PF=0
JCXZ Jump if CX is Zero CX’in değeri sıfır ise CX=0000
-JL Jump if Less Küçükse SF<>0F
-JNL Jump if Not Less Küçük değilse SF=0F
-JG Jump if Greater Büyükse ZF=0 and SF=0F
-JNG Jump if Not Greater Büyük değilse ZF=1 or SF<>0F
-JLE Jump if Less or equal Küçük veya eşitse ZF=1 or SF<>0F
-JGE Jump if Greater or Equal Büyük veya eşitse SF=0F
-JNLE Jump if Not Less nor Equal Küçük değil ve eşit değilse ZF=0 and SF=0F
-JNGE Jump if Not Greater nor Equal Büyük değil ve eşit değilse SF<>0F
-JO Jump if Overflow Taşma varsa OF=1
-JNO Jump if Not Overflow Taşma yoksa OF=0
-JS Jump if Sign Negatif ise SF=1
-JNS Jump if Not Sign Pozitif ise SF=0
*:İşaretli sayılar üzerinde yapılan operasyonlardan sonra kullanılır
-:hem işaretli hemde işaretsiz sayılar üzerinde yapılan operasyonlardan sonra kullanılır.
:* ve - işaretli olan komutlar işaretsiz sayılar üzerinde yapılan operasyonlardan sonra kullanılır.
3.3.6. ADD, MUL, DIV
Etkilenen bayraklar: [AF CF OF PF SF ZF]
Genel Yazım Formatı
ADD kaynak, hedef
ADD reg, reg
ADD reg, mem
ADD mem, reg
ADD mem, immed
Yapılan işlem sonrası gösterilen hedef, kaynağa eklenir. Örneğin;
MOV AX, 5
MOV BX, 3
ADD AX, BX
İşleminden sonra
AX=8
BX=3 olacaktır.
Çıkartma işlemi içinde aynı sırayı takip edebilirsiniz. Çıkartma, çarpma ve bölme aslında bir tür seri toplama işlemidir. Yani çıkartma işlemi içinde ADD kullanıyoruz. Örneğin 8’den 3’ü çıkartalım.
MOV AX, 8
ADD AX, -3
AX=5 olmuştur.
MUL (multiply)
Etkilenen bayraklar: [CF OF], [AF,PF,SF,ZF belirsiz]
MUL reg
MUL mem
IMUL
Bu kısımları özet olarak geçiyorum. MUL ile işaretsiz sayıları çarpabilirsiniz IMUL ilede işaretli sayıları çarpabilirsiniz.
Etkilenen bayraklar: [AF,CF,OF,PF,SF,ZF belirsiz]
DIV reg
DIV mem
IDIV
DIV (divide)
DIV ile işaretsiz sayıları IDIV ilede işaretli sayıları bölebilirsiniz.
3.3.7. Bazı komutlar (biraz bildiğini varsayanlar baksın)
CALL - RET
Bir tür prosedür gibi düşünebilirsiniz. Programı bu şekilde bölütlere ayırarak daha etkin kullanabilirsiniz. Bir CALL içine girildikten sonra RET komutu görülünceye kadar ilerlenir. (BASIC dilindeki gosub ve return komutu gibi;-)
PUSH - POP
PUSH, POP : genel amaçlı yığıtçılar
PUSHA, POPA : EDI, ESI, EBP, ESP, EDX, ECX, EAX sakla
PUSHF, POPF : bayrakların durumunu yığıtla
Kaydedici, Hafıza veya Durum Bayraklarını saklamanızı sağlar.
Şöyle düşünelim kullandığımız değişkenler çok sınırlı bir miktarda bunları bir şekilde bir yerlerde de saklamamız gerekli işte bunun için hafızada yığıt (stack) yaparız. Siz her saklama işlemi yaptığınızda hafızaya bir bilgi eklenir. {her yeni bilgi SS:SP’nin üstüne atılır.}
Daha sonra sakladığınız bilgileri geri çağırmak için POP’u kullanırız.
LOOP
Genel Yazım Formu : LOOP label
Genel amaçlı sayıcıdır. CX’ 0 olana kadar LABEL’a sürekli döner durur.
0100: MOV DX, 0
0103: MOV CX, 5
0106: ADD DX, CX
0108: LOOP 0106
program bitiminde dönen değerler böyle olur.
CX = 0 h
DX = F h
(for döngülerine benzetebilirsiniz)
3.4. Prototip Program ve Op Code için örnekler
***YORULDUM 10 SAAT OLDU ARTIK DİNLENİYİM ?***
ayrıca bana ulaşmak isterseniz. e-mail adresim altta.
Demiş miydim bilmiyorum ama kaynak göstererek de olsa iznim olmadan yayınlayamazsınız diye ???
Yazının başında da bahsettiğim gibi programlama dili seviyeleri yüksek ve düşük seviye olmak üzere ikiye ayrılır. Yüksek seviye programlama dilleri bizlerin daha basit kullandığı bir arayüze (InterFace) sahiplerdir. En yüksek seviye programlama dili bile bilgisayar tarafından anlaşılması için düşük seviye dile çevrilir. Yani siz hangi platformda programlama yaparsanız yapın bilgisayar bunu kendi anlayacağı dile çevirip işler. Buda assembly’dir. Assembly diğer dillere nazaran anlaşılması bir karmaşayı öğrenmeye benzer. Çünkü işlemler en basit mantık adımlarının bütünleşmesiyle oluşur.
Bu bütünün yapısını incelersek karşımıza kavramlar çıkar. Hafıza ve İşlemci tüm işlemlerin yürütüldüğü ve oluşumlar için ortam sağlayan kısımdır. Assembly düşük seviye bir dil olduğu için işlemlerde en basit adımlarla sırayla gerçekleşir. İşlemci ve Hafıza gerekli bilgiyi işledikten sonra bunları kullanması için çeşitli şekillerde dağıtacaktır. Ama biz bunun dağıtılması ve toplanmasını değil sadece işleyiş biçimini inceleyeceğiz.
Hafıza (Memory)
Bir defter gibi düşünebilirsiniz. Bilgi tutmaya yarayan bir araçtır. Elde edilen bilgiler, yapılacak işlemler, işlemlerin sonuçları vb. tüm bilgiler bu sayfalara yazılacaktır.
İşlemci (Processor)
Hafızadaki (defterdeki) tüm bilgileri okuyacak bunları değerlendirecek ve değerlendirme sonuçlarını tekrar deftere yazabilecektir hatta bu işlemler, başka birimleri ilgilendiriyorsa onlarla da iletişime geçecek ve onlarda da gerekli iletişim ve işlemleri yapacaktır.
Bir programın çalışması
Bir işlemcinin işleri en basit adımlarla sırayla yaptığını hatırlayalım. Onun için bizde bir programın çalışmasını sizlere
ÖZEL BAZI BİLGİLER
*Kaydediciler bir hafıza bölümü olması rağmen hafızanın içinde değil işlemcinin içinde yer alırlar.
Bunun iki ana sebebi vardır ilk olarak işlemci hafızaya göre çok üstün bir hızda çalışır. İkinci olarak ta işlemci bu bilgileri çok kullandığı için yolunu uzatmamış olur.
*Bir işlemci aynı anda sadece 1 iş yapabilir. Çünkü uyulması gereken sıra vardır fakat birbirini etkilemeyen komutlar artarda gelirlerse bunları birbirinden bağımsız olarak işleyip hız kazanabilir. Bu yeni nesil işlemcilerde karşılaştırma işlemlerinde dahi kullanılmaktadır. Böylece yavaş artan frekans yerine işlemlerin süresinden kazanç elde edilir.
Son düzenleme:
