Assembly Programlama Dili Konu Özeti ve Kod Örnekleri
6
Öncelikle işi büyük bir profesyönellik ile değil de daha çok hem öğrenmek hemde öğretmek adına yani okuyan arkadaşlara faydası dokunması için yazıyorum.Eksiklerim yada yanlışlarım olduğunda bildirmenizden memnuniyet duyarım.Şimdi konumuza şöyle bir giriş yapalım :
1- Data Registers -
Data registers kendi içerisinde 4 adet 16 bit kapasiteli registers'a sahiptir.Bunlar AX,BX,CX,DX adlarına sahiplerdir.
AX: Accumulator
BX : Base
CX : Count
DX : Data
Bu registers kendi aralarında 8 bit lik 2 gruba ayrılırlar.Bunlar:
AX(16 bit) için AH(8 bit) ve AL (8 bit)
BX(16 bit) için BH(8 bit) ve BL (8 bit)
CX (16 bit)için CH(8 bit) ve CL (8 bit)
DX (16 bit)için DH(8 bit) ve DL (8 bit) olarak adlandırılmaktadır.
AH ,16 bitlik AX register'ının 8 bitlik (High ) seviyeli bölümü olarak adlandırılmaktadır.
AL ise 16 bitlik AX register'ının 8 bitlik (Low ) seviyeli bölümü olarak adlandırılmaktadır.
Bu durum tahmin edebileceğiniz gibi diğer registers için de geçerlidir. H ve L harf eklemeleri bu noktadan gelmektedir.
Program yazarken 8 bitlik verilerin işlenmesinde bu 8 bit lik registers dan faydalanırız.Data registers döngülerde, matematiksel işlemlerde , interrupt kullanılması gibi birçok işlemde Central Prossesing Unit(CPU) tarafından yer ayrılmış yani rezervasyon edilmiş gibi düşünebiliriz.Dolayısı ile biz bizim registers içindeki bilgiyi değiştirme ihtimalimiz yoktur.
DİKKAT!!!
AX register’ımızın değeri C34F olsun. Bu durumda BH=C3 ve BL=4F
olur. Simdi BL’nin değerini 55 olarak değiştirelim. Son durumda BX=C355, BH=C3 ve
BL=55 olacaktır.
2- Pointer ve İndex Registers -
Bilgisayarımızda bir program çalıştırdığımız zaman program önce RAM’e yüklenir ve daha
sonra çalıştırılır. Yükleme işlemi programın kod, data gibi bölümlerinin çeşitli belek alanlarına
ayrı ayrı yüklenmesi ile yapılır. Bu alanlara segment adı verilir.Pointer ve index register’ları bellek içerisindeki herhangi bir noktaya erişmek için kullanılır.
Bu iş için erişilmek istenen noktanın offset ve segment adresleri gerekli register’lara atanarak
işlem gerçekleştirilir.
SP : Stack Pointer
BP : Base Pointer
SI : Source Index
DI : Destination Index
-SP : Stack Pointer
Stack'in en üst noktasını işaret eder.Bunun değeri otomatik olarak değişir.Peki stack dediğimiz şey nedir ? Stack dediğimiz şey bir segmenttir yani 64kb dediğimiz bir memorydir.Tabi bu arada 64 kb lık hafıza hafıza bloğuna ( memory - RAM ) segment denir.
4 çeşit Stack bulunmaktadır Bunlar :
-BP :Base Pointer
SP gibi davranmaktadır aralarındaki tek fark değerini değiştirebiliriz.
-SI : Source Index : Bellekten dosya alma operasyonlarında auto icrement kullanarak yardım eden değeri 0 olan işaretci.DI ise SI in aynısıdır fakat kaynak ve işaretci olarakta bazı string komutları tarafından kullanılır.
3 -Segment Registerları-
Bu registers yazılan programın çeşitli kısımlarının adres değerlerini tutar.
4 tip segment register vardır bunlar :
CS,SS,DS,ES dir.
CS:Yazdığımız programın kodunun başlangıç adresi bulunmaktadır.
SS : Stack(yığın) ın adresi var
DS: Programın datalarının başlangıç adresi bulunmaktadır.
ES :Ekstradan kullanılacak olan segment adresi vardır.
4-Instruction Pointer-
Instruction Pointer register’ı işlemci tarafından işlenecek bir sonraki komutun bellekteki
adresini saklar. Bu register üzerinde programcı tarafından herhangi bir işlem yapılamaz. Her
komut işletildikten sonra CPU otomatik kullanılan komuta göre gerekli değeri bu register’a atar.
5- Flag Register-
Flag Register diğer register’lardan daha farklı bir durumdadır. Diğer resigterların 16-bit
halinde bir bütün olarak ele alınmalarından farklı olarak flag register’ın her biti CPU için ayrı
bir değere sahiptir (8086 işlemci tarafından sadece 9 tanesi kullanılmaktadır). Bu bitlerin özel
olarak isimlendirilmeleri aşağıda verilmiştir.
C : Carry flag
A : Auxilary Carry flag
Z : Zero flag
O : Overflow flag
D : Direction flag
I : Interrupt flag
T : Trace flag
S : Sign flag
P : Parity flag
CARRY FLAG
Burada işlemcinin herhangi bir işlem yaptığını düşünün daha sonra yaptığı bu işlem sonucunda alıcı alana bunu yerleştirmeye çalışıyorsunuz fakat bir bakıyoruz ki bu alıcı alana sığmıyor bizim sayımız yani sayı alana büyük geliyor işte bu olaya biz "carry"(taşma) diyoruz. CPU böyle bir durumla karşılaştığında Carry Flag değeri "1" olarak alınıyor
şimdi bu duruma bir örnek verelim :
1111 1001 0110 1010 ----------- F96A
0010 1010 1111 1001 ----------- 2AF9
+-----------------------------------------
1 0010 0100 0110 0011 -------------2463
F96A ve 2AF9 sayılarının toplanması sonucunda 2463 sayısı elde edilmiştir ki bu sayı toplanan iki sayıdan da küçüktür dolayısı ile böyle birşey imkansızdır fakat CPU carry flag'i dediğimiz şeyi 1 yapar ve 17 bit lik bir sayı elde ederiz.
Yukarıdaki kodda ilk olarak mov komutu ile F96A değeri AX register'ının içine atanmıştır .Bir sonraki mov komutunda ise 2AF9 değeri BX register'ının içine atanmış ve son olarakta ADD komutu ile AX değeri ve BX değeri toplanıp AX register'ının içine atanmıştır.Programda kullandığımız komutlar ileride anlatılacaktır fakat burada kısa bir şekilde açıklamaya çalıştım T ise işlemleri adım adım görmemi sağlamaktadır. ilk t ye bastığımda 1. komutu uyguladı ve AX registerına F96A değerini atadığını görüyorsunuz daha sonra BX register'ına 2AF9 değerini atamış olduğunu ve son t ye basışımızdada ikisinin toplamı olan 2463 değerini AX registerına atamıştır. Fark ederseniz eğer en sağda her komuttan sonra NC var fakat son komutta taşma biti carry flag den dolayı o da CY olmuştur.
Auxilary Carry Biti
CPU tarafından gerçekleştirilen işlem sonucunda alıcı alanın ilk dört biti üzerinde bir taşma
gerçekleşiyorsa bu flagın değeri 1 yapılır.
Zero flag
Yapılan işlem sonucu sıfır ise zero flag olur aşşagıdaki örneği inceleyelim :
Yukarıdaki örnekte öncelikle mov komutu ile ax register'ına f92a değeri atanmıştır daha sonra xor komutunu kullanarak ax ve ax xor edilmiştir ve aynı iki sayının xor edilmesi sonucu sıfırdır yani artık ax registerımızın yeni değeri sıfırdır ve Zero F lag den dolayı da 19. satırdaki NZ 23. satıtda ZR ye yani zero flag e dönüşmüştür.
Overflow Flag
İşaretli sayılar üzerindeki taşmayı kontrol etmek için kullanılır.pozitif olan bir sayının taşma sonucu negatif olması mümkündür bu durumda owerflow flag kullanılır. Owerflow flag set edilir ve yanlış algılaması engellenmiş olur.
Direction Flag
Dizgi işlemleri üzerindeki işlemin yönünü belirtmek için kullanılır.
İnterrup Flag
CPU’nun çeşitli aygıtlardan gelen kesme isteklerini dikkate alıp almayacağını bildirir. 0 olması
durumunda istekler dikkate alınmayacaktır.
Trace Flag
CPU’nun sadece bir komut çalıştırıp beklemesi için kullanılır. DEBUG’ın kullandığı “Trace”
işlemi bu flagın set edilmesi ile gerçekleştirilir.
Sign Flag
İşaretli sayılarda bayt (8 bit) için sayının 7. ve word (16 bit) için sayının 15. biti işaret biti
olarak adlandırılır. Yapılan bir işlem sonucunda alıcı alan içersindeki işaret biti sign flag
içerisine kopyalanır. Yani sign flag değeri 0 ise elde edilen sonuç pozitif, 1 ise elde edilen
sonuç negatif kabul edilir.
BELLEK VE YAPISI
Segment dediğimiz olayın diğer bir adı da yani Türkçeleştirmeye çalışırsak eğer bölüt diyebiliriz bazı kaynaklarda bölüt olarak da geçmektedir fakat bilgisayar terimlerini Türkçeleştirmeye çalışmak ne kadar doğru olur orası da ayrı bir meçhul tabiki . Segment dediğimiz şey belleğin bir bölgesine verilen addır daha öncede belirttiğimiz gibi hafıza içerisi bölüm bölümdür bu bölümlerden birine segment diyebiliriz.Segmentler 4 e ayrılıyor kod segment,data segment,yığıt segment,ek segment.
Kod segmentde çalıştırılacak program tutulur.
Data segmentde saklanan ve okunan değerler için veri yazma ve aktarma alanıdır.
Yığıt(stack) segment pop,push gibi yığıt işlemi yapan komutlar içerir.
Ek segment ekstra işlemler için kullanılır.
8086 İŞLEMCİLERDE BELLEK ADRESLEME
Bildiğimiz üzere 8086, 80186, 80286, 80386,80486 ve Pentium işlemcileri intel'in 80x86 serisi adı altında toplanmıştır.Bizim yapmaya çalıştığımız şey ise bu bölümde bu işlemciler için 16-bit lıik programlama dilini öğrenmeye çalışmak olacaktır.
Assembly programlama dili düşük seviyeli bir dilidir. Bilgisayarınız aslında makine dili üzerine kuruludur siz bir şey yazarsınız makine diline yani kendi algılayacağı dile çevirir ona göre işlemler yapar.Makine dilinin kullanıcılar tarafından anlaşılır haline gelmişine ise assembly dili diyebiliriz C ,C++,Pascal gibi diller ise yüksek seviye diller arasında yer almaktadır.Bir yazılımcı Assembly dili ile uğraşırken doğrudan hafıza ve işlemci ile uğraşır yani bilgisayarın beyninde olduğunuzu düşünebilirsiniz.Bu da hafızadaki (RAM) ve işlemcideki değerleri doğrudan değiştirme imkanına sahipsiniz demek oluyor.Assembly dilinin çok güzel bir özelliği vardır oda boyutunun diğer programlara göre çok düşük seviyede olmasıdır.
Yukarıdaki resimde de gördüğünüz gibi 3 dilde de aynı işlemler yapılmıştır ve aslında aynı anlama gelen kodlar yazılmıştır fakat bu kodların her dildeki boyutları farklıdır Assembly dilinin boyutu diğer 2 dilin boyutuna göre çok çok küçük olduğu görülmektedir. C dili ile yazılan koddan 1000 kat dan daha az bir boyuta sahiptir. Pascal dilinin boyutuyla karşılaştırmaya çalışmak bile şu durumda ayıptır. Şimdi ise kısa bir özet ile veri tiplerini hatırlayalım ve daha sonra mikroişlemciler yapısı registerlar ve assembly dili için bize gerekli olan komutlardan bahsedeceğim.
Veri Tipleri
1. Bit
"Binary Digit'in" kısaltılması sonucu oluşmuştur.Bilgisayar ikili sayı sisteminden oluşmaktadır bu sayı basamakların her birine binary digit adı verilmiştir.ya 0 olur yada 1 olur.En küçük bilgi birimi bit'dir.
2. Bayt
8 adet bitin oluşturduğu topluluğun adıdır.
en küçük bayt : 00000000 olur ve bu da 0'dır.
en büyük bayt : 11111111 olur ve bu da 255'dir.
3.Word
Word ise 2 bayt'ın birleşmesi sonucu oluşur.16 bit bilgi bulundurur. Tabiki demin bayt da yaptığımız gibi word'ün alabileceği inimal ve maksimal değerleri hesaplamamız da mümkündür.
4.Double Word (LONG)
Tahmin edebileceğiniz gibi iki ayrı word ün birleşmesi sonucu oluşur.32 bit lik bilgiyi içerisinde barındırır.
MİKROİŞLEMCİ(CPU) VE BELLEK YAPISI
Kullandığımız bilgisayarlarda bilgileri okuyan ve işleyen kısım merkezi işlem ünitesidir yani CPU(Central Prossesing Unit). – CPU bellek ve çeşitli giriş / çıkış üniteleri ile bus adı verilen veri yollarını kullanarak haberleşmektedir.
İşlemci, register adı verilen bölmelerden oluşur. Bu registerlar :
1. Data Registerları
2.Pointer ve İndex Registerları
3. Segment Registerları
4. İnstruction Pointer (Komut göstergeci)
5.Flag Registerları
1- Data Registers -
Data registers kendi içerisinde 4 adet 16 bit kapasiteli registers'a sahiptir.Bunlar AX,BX,CX,DX adlarına sahiplerdir.
AX: Accumulator
BX : Base
CX : Count
DX : Data
Bu registers kendi aralarında 8 bit lik 2 gruba ayrılırlar.Bunlar:
AX(16 bit) için AH(8 bit) ve AL (8 bit)
BX(16 bit) için BH(8 bit) ve BL (8 bit)
CX (16 bit)için CH(8 bit) ve CL (8 bit)
DX (16 bit)için DH(8 bit) ve DL (8 bit) olarak adlandırılmaktadır.
AH ,16 bitlik AX register'ının 8 bitlik (High ) seviyeli bölümü olarak adlandırılmaktadır.
AL ise 16 bitlik AX register'ının 8 bitlik (Low ) seviyeli bölümü olarak adlandırılmaktadır.
Bu durum tahmin edebileceğiniz gibi diğer registers için de geçerlidir. H ve L harf eklemeleri bu noktadan gelmektedir.
Program yazarken 8 bitlik verilerin işlenmesinde bu 8 bit lik registers dan faydalanırız.Data registers döngülerde, matematiksel işlemlerde , interrupt kullanılması gibi birçok işlemde Central Prossesing Unit(CPU) tarafından yer ayrılmış yani rezervasyon edilmiş gibi düşünebiliriz.Dolayısı ile biz bizim registers içindeki bilgiyi değiştirme ihtimalimiz yoktur.
DİKKAT!!!
AX register’ımızın değeri C34F olsun. Bu durumda BH=C3 ve BL=4F
olur. Simdi BL’nin değerini 55 olarak değiştirelim. Son durumda BX=C355, BH=C3 ve
BL=55 olacaktır.
2- Pointer ve İndex Registers -
Bilgisayarımızda bir program çalıştırdığımız zaman program önce RAM’e yüklenir ve daha
sonra çalıştırılır. Yükleme işlemi programın kod, data gibi bölümlerinin çeşitli belek alanlarına
ayrı ayrı yüklenmesi ile yapılır. Bu alanlara segment adı verilir.Pointer ve index register’ları bellek içerisindeki herhangi bir noktaya erişmek için kullanılır.
Bu iş için erişilmek istenen noktanın offset ve segment adresleri gerekli register’lara atanarak
işlem gerçekleştirilir.
SP : Stack Pointer
BP : Base Pointer
SI : Source Index
DI : Destination Index
-SP : Stack Pointer
Stack'in en üst noktasını işaret eder.Bunun değeri otomatik olarak değişir.Peki stack dediğimiz şey nedir ? Stack dediğimiz şey bir segmenttir yani 64kb dediğimiz bir memorydir.Tabi bu arada 64 kb lık hafıza hafıza bloğuna ( memory - RAM ) segment denir.
4 çeşit Stack bulunmaktadır Bunlar :
- STACK SEGMENT : Registerların ya da başka değişkenlerinin değerlerini saklamak için kullanılır.Stack de LİFO(Last İn First Out) denen bir sistem vardır yani bu sistemi bir çöp kutusu gibi düşünebilirsin çöpe en son attığın şey ilk başta gözükmektedir.En son koyduğunuz şey stack in en tepesinde yer alır.
- DATA SEGMENT : Bu bölümde datalar ve sabitler bulunur.
- CODE SEGMENT : Bu bölümde programınızın kodu bulunur.
- EXTRA SEGMENT : Özel amaçlı kullanılmaktadır.
-BP :Base Pointer
SP gibi davranmaktadır aralarındaki tek fark değerini değiştirebiliriz.
-SI : Source Index : Bellekten dosya alma operasyonlarında auto icrement kullanarak yardım eden değeri 0 olan işaretci.DI ise SI in aynısıdır fakat kaynak ve işaretci olarakta bazı string komutları tarafından kullanılır.
3 -Segment Registerları-
Bu registers yazılan programın çeşitli kısımlarının adres değerlerini tutar.
4 tip segment register vardır bunlar :
CS,SS,DS,ES dir.
CS:Yazdığımız programın kodunun başlangıç adresi bulunmaktadır.
SS : Stack(yığın) ın adresi var
DS: Programın datalarının başlangıç adresi bulunmaktadır.
ES :Ekstradan kullanılacak olan segment adresi vardır.
4-Instruction Pointer-
Instruction Pointer register’ı işlemci tarafından işlenecek bir sonraki komutun bellekteki
adresini saklar. Bu register üzerinde programcı tarafından herhangi bir işlem yapılamaz. Her
komut işletildikten sonra CPU otomatik kullanılan komuta göre gerekli değeri bu register’a atar.
5- Flag Register-
Flag Register diğer register’lardan daha farklı bir durumdadır. Diğer resigterların 16-bit
halinde bir bütün olarak ele alınmalarından farklı olarak flag register’ın her biti CPU için ayrı
bir değere sahiptir (8086 işlemci tarafından sadece 9 tanesi kullanılmaktadır). Bu bitlerin özel
olarak isimlendirilmeleri aşağıda verilmiştir.
C : Carry flag
A : Auxilary Carry flag
Z : Zero flag
O : Overflow flag
D : Direction flag
I : Interrupt flag
T : Trace flag
S : Sign flag
P : Parity flag
CARRY FLAG
Burada işlemcinin herhangi bir işlem yaptığını düşünün daha sonra yaptığı bu işlem sonucunda alıcı alana bunu yerleştirmeye çalışıyorsunuz fakat bir bakıyoruz ki bu alıcı alana sığmıyor bizim sayımız yani sayı alana büyük geliyor işte bu olaya biz "carry"(taşma) diyoruz. CPU böyle bir durumla karşılaştığında Carry Flag değeri "1" olarak alınıyor
şimdi bu duruma bir örnek verelim :
1111 1001 0110 1010 ----------- F96A
0010 1010 1111 1001 ----------- 2AF9
+-----------------------------------------
1 0010 0100 0110 0011 -------------2463
F96A ve 2AF9 sayılarının toplanması sonucunda 2463 sayısı elde edilmiştir ki bu sayı toplanan iki sayıdan da küçüktür dolayısı ile böyle birşey imkansızdır fakat CPU carry flag'i dediğimiz şeyi 1 yapar ve 17 bit lik bir sayı elde ederiz.
Yukarıdaki kodda ilk olarak mov komutu ile F96A değeri AX register'ının içine atanmıştır .Bir sonraki mov komutunda ise 2AF9 değeri BX register'ının içine atanmış ve son olarakta ADD komutu ile AX değeri ve BX değeri toplanıp AX register'ının içine atanmıştır.Programda kullandığımız komutlar ileride anlatılacaktır fakat burada kısa bir şekilde açıklamaya çalıştım T ise işlemleri adım adım görmemi sağlamaktadır. ilk t ye bastığımda 1. komutu uyguladı ve AX registerına F96A değerini atadığını görüyorsunuz daha sonra BX register'ına 2AF9 değerini atamış olduğunu ve son t ye basışımızdada ikisinin toplamı olan 2463 değerini AX registerına atamıştır. Fark ederseniz eğer en sağda her komuttan sonra NC var fakat son komutta taşma biti carry flag den dolayı o da CY olmuştur.
Auxilary Carry Biti
CPU tarafından gerçekleştirilen işlem sonucunda alıcı alanın ilk dört biti üzerinde bir taşma
gerçekleşiyorsa bu flagın değeri 1 yapılır.
Zero flag
Yapılan işlem sonucu sıfır ise zero flag olur aşşagıdaki örneği inceleyelim :
Yukarıdaki örnekte öncelikle mov komutu ile ax register'ına f92a değeri atanmıştır daha sonra xor komutunu kullanarak ax ve ax xor edilmiştir ve aynı iki sayının xor edilmesi sonucu sıfırdır yani artık ax registerımızın yeni değeri sıfırdır ve Zero F lag den dolayı da 19. satırdaki NZ 23. satıtda ZR ye yani zero flag e dönüşmüştür.
Overflow Flag
İşaretli sayılar üzerindeki taşmayı kontrol etmek için kullanılır.pozitif olan bir sayının taşma sonucu negatif olması mümkündür bu durumda owerflow flag kullanılır. Owerflow flag set edilir ve yanlış algılaması engellenmiş olur.
Direction Flag
Dizgi işlemleri üzerindeki işlemin yönünü belirtmek için kullanılır.
İnterrup Flag
CPU’nun çeşitli aygıtlardan gelen kesme isteklerini dikkate alıp almayacağını bildirir. 0 olması
durumunda istekler dikkate alınmayacaktır.
Trace Flag
CPU’nun sadece bir komut çalıştırıp beklemesi için kullanılır. DEBUG’ın kullandığı “Trace”
işlemi bu flagın set edilmesi ile gerçekleştirilir.
Sign Flag
İşaretli sayılarda bayt (8 bit) için sayının 7. ve word (16 bit) için sayının 15. biti işaret biti
olarak adlandırılır. Yapılan bir işlem sonucunda alıcı alan içersindeki işaret biti sign flag
içerisine kopyalanır. Yani sign flag değeri 0 ise elde edilen sonuç pozitif, 1 ise elde edilen
sonuç negatif kabul edilir.
BELLEK VE YAPISI
Segment dediğimiz olayın diğer bir adı da yani Türkçeleştirmeye çalışırsak eğer bölüt diyebiliriz bazı kaynaklarda bölüt olarak da geçmektedir fakat bilgisayar terimlerini Türkçeleştirmeye çalışmak ne kadar doğru olur orası da ayrı bir meçhul tabiki . Segment dediğimiz şey belleğin bir bölgesine verilen addır daha öncede belirttiğimiz gibi hafıza içerisi bölüm bölümdür bu bölümlerden birine segment diyebiliriz.Segmentler 4 e ayrılıyor kod segment,data segment,yığıt segment,ek segment.
Kod segmentde çalıştırılacak program tutulur.
Data segmentde saklanan ve okunan değerler için veri yazma ve aktarma alanıdır.
Yığıt(stack) segment pop,push gibi yığıt işlemi yapan komutlar içerir.
Ek segment ekstra işlemler için kullanılır.
8086 İŞLEMCİLERDE BELLEK ADRESLEME
Hocam devamı yok mu? Çok sade ve iyi anlatmışsınız
YanıtlaSilsağol
YanıtlaSilsağol kardeşim
YanıtlaSilGayet yararlı, teşekkür ederim
YanıtlaSilanlamadım abi siz nasıl anladınız benim beynim yandı çok sinirliyim
YanıtlaSilBu tür bilgiler bir bilgisayar yazılımcısı için yol gösterici bilgilerdir.
YanıtlaSil