Professional Documents
Culture Documents
Mikroişlemciler Ve Assembly Notları
Mikroişlemciler Ve Assembly Notları
Sistem Organizasyonu
80X86 assembly dilinde program yazmak, bilgisayarın donanım yapısını ve Von Neuman mimarisini
anlamayı gerektirir. Bu mimari, merkezi işlem birimi, bellek ve giriş-çıkış birimleri olmak üzere üç
temel parçaya dayanır ve bu birimlerin birbirleriyle veri yolu üzerinden iletişim kurduğu bir yapıdır.
Programlama sırasında, bilgisayar bileşenlerinin nasıl etkileşime girdiğini ve veri, adres ve kontrol
yollarının işlevlerini bilmek önemlidir. Zamanla, bilgisayarın temel parçaları gelişmiş ve farklı
ihtiyaçları karşılamak üzere yeni yol tipleri oluşturulmuştur.
Önemli Noktalar:
- ** Von Neuman Mimarisi: ** Merkezi işlem birimi, bellek ve giriş-çıkış birimlerinden oluşur,
bu birimler veri yolu üzerinden iletişim kurar.
- ** Birimler Arası İletişim: ** Veri, adres ve kontrol yolları, bilgisayarın farklı bölümleri
arasında veri aktarımını sağlar.
- ** Programlama ve Kontrol: ** Donanımın yapısını ve işletim sistemleriyle olan etkileşimini
anlamak, etkili programlama için kritiktir.
- ** Yol Tipleri ve Gelişim: ** Bilgisayarın evrimi, veri genişliği, dönüş hızı ve aygıt yönetimi
gibi özelliklere sahip farklı yol tiplerinin geliştirilmesine yol açmıştır.
Önemli Noktalar:
- **Bellek Bağlantı Yuvaları:** Anakart ile bellek birimleri arasındaki bağlantıyı sağlar.
- **DIP, SIMM ve DIMM Modülleri:** Bellek birimlerinin evrimi ve çeşitlenmesi, veri
aktarım kapasiteleri ile belirlenir.
- **Veri Genişliği ve Hız:** Bellek modüllerinin performansını etkileyen ana faktörler.
- **Bacak Dizilişi ve Çentik Konumu:** Modüller arasındaki farklılıkları ve uyumluluğu
belirleyen özellikler.
Önemli Noktalar:
- **Uzatılmış Bellek:** 1 MB üzeri belleğin işlemciler tarafından doğrudan adreslenebildiği
bölge.
- **Adresleyebilme Kapasitesi:** İşlemcinin adres bacaklarının sayısı ile orantılıdır.
- **Kullanım ve Yönetim:** DOS 4.0 ve üstü işletim sistemlerinde özel aygıt sürücüleri ile;
yeni nesil işletim sistemlerinde korumalı kip düz modeli ile yönetilir.
- **Tasarım Değişiklikleri:** İşlemcinin uzatılmış bellek alanına erişimini desteklemek için
gerekli.
3.2. 80x86 İşlemcisinin İç Yapısı
3.3. Kesim (Segment) Yapısı
8086 işlemcisinin 20 adres bacağına karşın, en büyük yazmacı 16 bit olup, bu yüzden doğrudan 64
KB'den fazla belleği adresleyemez. Bu sınırlılığı aşmak için kesimli bellek yönetim tekniği
geliştirilmiştir. 80X86 işlemci ailesi, ana belleği 64 KB'lık kesimlere ayırarak ve kesim yazmaçları ile
işaretçiler kullanarak belleğin tümünü kullanabilir. Bu yapı, belleğe erişimde esneklik sağlar ve
programlama açısından önemli bir avantaj sunar.
Önemli Noktalar:
- **20 Adres Bacakları:** 8086 işlemcisinin sahip olduğu, ancak 1 MB'lık belleğe tam erişim
sağlayamama sorunu.
- **Kesimli Bellek Yönetimi:** 64 KB üzeri belleği adreslemek için geliştirilen yöntem.
- **Ana Belleğin Bölünmesi:** Belleğin 64 KB'lık kesimlere ayrılması.
- **Kesim Yazmaçları:** CS, SS, DS, ve ES; bellek kesimlerine erişim sağlayan yazmaçlar.
- **Kesim İçi İşaretçiler:** Bellek kesimleri içindeki göreli konumları belirleyen değerler.
Önemli Noktalar:
- **Veri Kesimi:** Programın işleyeceği giriş ve çıkış değerlerinin bulunduğu bellek bölümü.
- **Tanımlamalar:** Veri tipine bağlı olarak programcı tarafından yapılır.
- **Başlangıç Adresi:** DS yazmacı ile belirlenir.
- **İç Adresleme:** SI, DI, ve BX yazmaçları kullanılarak yapılır.
Komut adresleme CS IP -
**Kesim Grubu Yazmaçları:** Bellek
Yığıt adresleme SS SP, BP kesimlerinin başlangıç adreslerini belirler.
Veri adresleme DS SI, DI, BX - **Göreli Konum Değeri:** Kesim
Veri adresleme ES DI, SI, BX içindeki verinin yerini gösterir.
- **Kesim Büyüklüğü:** 8086/8088
işlemcilerde 64 KB, 80386 ve üstü işlemcilerde 4 GB'a kadar çıkabilir.
- **Kesim Organizasyonu:** 8086/8088 ve 80386 üstü modellerde benzer, ancak büyük
kesimler korumalı kipte kullanılır.
3.5. Bayraklar
İşlemciler, PSW (Programme Status Word) adı verilen özel bir yazmaç kullanarak işlem sonuçlarını
bayraklar aracılığıyla takip eder. Bu bayraklar, işlemcide gerçekleştirilen işlemlerin sonuçlarını bir bit
büyüklüğünde değerlerle ifade eder. 8086 işlemcisi, bu tip durumları belirtmek için 9 adet bayrağa
sahiptir ve bu bayraklar 0 veya 1 değerlerini alabilir.
Önemli Noktalar:
- **PSW (Programme Status Word)**: İşlemlerin sonucunu belirten özel değerleri tutan
yazmaç.
- **Bayraklar**: İşlem sonuçlarını ifade eden, 0 veya 1 değerini alan bir bit büyüklüğünde
değerler.
- **Bayrakların Sayısı**: 8086 işlemcide toplam 9 adet bayrak bulunmaktadır.
- **Değerlerin Anlamı**: 1 değeri bayrağın set edildiğini (birleme), 0 değeri ise clear (silme)
veya reset (sıfırlama) edildiğini gösterir.
3.5.1. CF: Carry Flag
8'li ve 16'lı işlemlerde oluşan elde/ödünç durumunu kullanıcıya belirtmek için CF bayrağının değeri 1
yapılır.
3.5.2. PF: Parity Flag
İşlem sonucunda çift eşlik (even parity) var ise (yani 1'lerin sayısı çift ise) durumu kullanıcıya
belirtmek için PF bayrağının değeri 1 yapılır. Eğer bit dizilişindeki 1'lerin sayısı tek ise (odd parity) PF
bayrağının değeri 0 yapılır.
3.5.3. AF: Auxilary Flag
8'li işlemlerde düşük anlamalı 4'lüden (nibble) yüksek anlamlı 4'lüye elde/ödünç, 16'lı işlemlerde
düşük anlamlı 8'liden yüksek anlamlı 8'liye elde/ödünç aktarımı durumun kullanıcıya belirtmek için
AF bayrağının değeri 1 yapılır.
3.5.4. ZF: Zero Flag
İşlem sonucunun sıfır çıkması durumunu (eşitlik olmasını) kullanıcıya belirtmek içi ZF bayrağının
değeri 1 yapılır.
3.5.5. SF: Sign Flag
İşlem sonucunda sayının negatif olduğunu (en anlamlı bit 1 ise) kullanıcıya belirtmek için SF bayrağın
değeri 1 yapılır.
3.5.6. TF: Trap Flag
Adım bayrağı olarak adlandırılır. TF bayrağının değeri 1 alması durumunda komut yürütüldükten
sonra bir kesme üretilir. Durumun kullanıcı tarafından izlenmesine olanak verir. (single step mode)
3.5.7. IF: Interrupt Flag
IF, maskelenebilir kesme (maskable interrupt) isteklerinin izinli olup olmadığını belirlemek için
kullanılır. IF bayrağının değerinin sıfır olması durumunda INT komutu kullanılarak üretilen her türlü
maskelenebilir kesme devre dışı kalır.
3.5.8. DF: Direction Flag
Dizgi işlemlerinde işlemin yüksek adresli bellekten başlayarak düşük adresli belleğe doğru
yürütülebilmesi için DF bayrağının değeri 1 yapılır. Aksi halde işlem düşük bellek adreslerinden
başlayarak yüksek bellek adreslerine doğru gerçekleştirilecektir.
3.5.9. OF: Overflow Flag
Aritmetik taşma olması durumunu kullanıcıya belirtmek için OF bayrağının değeri 1 yapılır. Aritmetik
taşma işaretli sayılar ile yapılan işlemlerde elde edilen işaretli sonucun tanımlı alana sığmaması
(taşması) durumunu belirtmektedir.
3.6. 16/32 Bitlik İşlemciler Arasındaki Farklılıklar
16 ve 32 bit işlemciler arasındaki farklar, çalışma kipleri ve işlemci mimarilerindeki detaylara
dayanmaktadır. 32 bit işlemciler, gerçek ve korumalı olmak üzere iki farklı çalışma kipi sunar ve
özellikle korumalı kipte, genişletilmiş yazmaç setleriyle birlikte daha kapsamlı bir işlevsellik sağlar.
16 bit işlemciler ise sınırlı yazmaç setiyle daha basit işlemler için tasarlanmıştır.
Önemli Noktalar:
- **Çalışma Kipleri**: 16 bitlik işlemciler yalnızca temel işlemleri desteklerken, 32 bitlik
işlemciler gerçek ve korumalı olmak üzere iki farklı kipi destekler.
- **Yazmaçlar**: 32 bit işlemciler, gerçek kipte 16 bitlik yazmaçlar kullanırken, korumalı kipte
ek yazmaçlar ve bayraklar (EAX, EBX, vs.) ile daha gelişmiş işlemler gerçekleştirilebilir.
- **Genişletilmiş Yazmaç Seti**: 32 bitlik korumalı kipte, yazmaçların isimlerinin başına "E"
harfi eklenmiş genişletilmiş yazmaç seti kullanılır.
- **Kod Uyumluluğu**: Hem 8 hem de 16 bitlik işlemler, önceki işlemcilerle tamamen kod
uyumlu olarak çalışır.
- **Kesim Yazmaçları**: GS ve FS yazmaçlarının eklenmesiyle kesim yazmaç sayısı altıya
çıkar.
- **Bayraklar**: 16 bitlik işlemcilerdeki bayraklara, korumalı kipte çalışma sırasında ihtiyaç
duyulan ek bayraklar (AC, VM, RF, vs.) eklenmiştir.
3.7. 64 Bit İşlemci Yazmaçları
64 bit işlemciler, 16 adet genel amaçlı yazmaç içerir ve bu yazmaçlar 32 bit ve 64 bit işlenenlerle
uyumlu şekilde çalışır. 32 bit işlenenler için EAX, EBX gibi yazmaçlara ek olarak R8D-R15D
şeklinde 8 ek yazmaç, 64 bit işlenenler için ise RAX, RBX gibi yazmaçlar kullanılır. Yazmaç
adlandırmalarında belirli bir hiyerarşi bulunur; R ön eki eklenerek 64 bite, E ön ekiyle 32 bite, hiçbir
ön ek olmadan 16 bite ve sonuna L eklenerek 8 bite erişilir. Yeni eklenen R8-R15 yazmaçları da
benzer şekilde farklı boyutlarda verilere erişim sağlar. Ancak, byte yazmaçlarına erişimde bazı
sınırlamalar mevcuttur ve bu sınırlamalar REX ön ekiyle aşılmaktadır.
Önemli Noktalar:
- **Genel Amaçlı Yazmaçlar:** 16 adet, 32 ve 64 bit işlenenlerle uyumlu.
- **Ek Yazmaçlar:** R8D-R15D, 32 bit işlenenler için eklenmiştir.
- **Yazmaç Hiyerarşisi:** R, E ön ekleri ve H, L son ekleriyle farklı bit boyutlarına erişim.
- **Byte Yazmaçlarına Erişim Sınırlaması:** AH, BH gibi yazmaçlar ile yeni byte yazmaçları
aynı anda kullanılamaz, REX ön eki bu sınırlamayı aşar.
1004H 22220000H
1000H 33330000H
0FFCH 44440000H
GDT
33330000H+ 1F00H=33331F0H
Önemli Noktalar:
- **Etiket ve Anımsatıcı Kullanımı:** Etiketler ":" ile, işlemler "," ile ayrılır.
- **İşlenenler:** İlk işlenen hedef, ikinci işlenen kaynaktır.
- **Yorumlar:** “;” ile başlar, derleyiciler tarafından işlenmez.
- **Derleyici İşlevi:** Sembolik komutları makine koduna çevirir.
- **Anımsatıcıların İşleyeceği İşlenen Sayısı:** İşlemcinin mimarisine bağlı olarak değişir.
- **Geliştirme Araçları:** NASM ve GDB, komut satırı üzerinden çalışır.
- **Metin Editörleri:** "geany" gibi renklendirme özelliği olan editörler tercih edilebilir.
Makefile'ı anlamak için dosyanın sondan başa doğru okunması gerekir çünkü makefile, üretilecek
programın bağımlılıklarını ters ağaç yapısı şeklinde sıralar. Örneğin, "merhaba" çalıştırılabilir
dosyasını oluşturmak için öncelikle "merhaba.o" nesne dosyasına ihtiyaç duyulur ve bu nesne dosyası
"merhaba.asm" kaynak dosyasından derlenir. Derleme ve bağlama işlemi için gerekli komutlar ve
seçenekler her dosya için belirtilmiştir. Assembly dilinde yazılan programın derlenmesi için NASM
derleyicisi kullanılmakta ve NASM'e çeşitli seçenekler ile parametreler tanımlanarak
çalıştırılmaktadır.
NASM derleyicisi, "-f" seçeneğiyle elf64 dosya formatında derleme yapar; "-g" ve "-F dwarf"
seçenekleri hata ayıklama bilgilerinin nesne dosyasına eklenmesini sağlar. Bu terimler, J.J.R.
Tolkien'in eserlerindeki "Elf" ve "Dwarf" karakterlerinden esinlenmiştir. Ayrıca, "-l" seçeneğiyle
derleme işleminden sonra oluşan nesne dosyasının detaylarını gösteren bir liste dosyası (.lst)
oluşturulur. Assembly kodunun nesne koduna dönüştürülmesi sonrası, bağlayıcı ve derleme işlemleri
gcc ile tamamlanır.
GCC derleyicisi, Assembly diliyle yazılan programların C standart kütüphane fonksiyonlarına
erişimini sağlar, böylece assembly kodunda hazır kütüphaneler kullanılarak program kodu küçültülür.
"-o" seçeneği, oluşturulacak programın adını belirtirken, "-no-pie" seçeneği, Position Independent
Executable formatında oluşturulmayacağı anlamına gelir. "#", yorum satırlarını belirten bir işarettir.
Programın inşası için "make" komutu kullanılır ve işlem tamamlandığında gerekli dosyalar
oluşturulmuş olur. Program, "./merhaba" komutu ile çalıştırılabilir.
Tipi Büyüklüğü Adı Yukarıdaki program içerisinde msj adlı değişken byte
db 8 bit Byte büyüklüğündeki bir veri olarak tanımlanmıştır.
dw 16 bit Word
dd 32 bit Double word msj db "merhaba, dunya",0
dg 64 bit Quadword
Aslında değişken bir bir byte büyüklüğündeki bir veriyi belirtmemektedir. Tersine, 13 karakter
uzunluğundaki bir dizgeyi belirtmektedir. Dizgenin okunması için bellekte “m” harfinin bulunduğu ilk
bellek adresinden itibaren “null terminator” yani “0” kadar olan bellek adreslerinin veriyi barındırdığı
belirtilmektedir. Buradaki sıfır ASCII karakter tablosundaki sayısal sıfır değildir.
ASCII tablosunun ilk elemanıdır. Komut satırından “man ascii” yazıldığında ASCII tablosuna
erişebilirsiniz. Yapılan tanımlama ile her seferinde bir byte veri okunacak ve null terminator
gelindiğinde ise okuma işlemi sona erecektir. Bu nedenle dizgeler için ayrı bir veri tipi tanımlanmasına
gerek yoktur.
Bu bölümde aynı zamanda program içerisinde kullanılacak olan ve değeri sabit kalacak olan
değişkenler yani sabitler tanımlanabilir. Örneğin bir aritmetik işlemde Pi sayısının kullanılacağını
düşünelim. Sabit değer olan Pi sayısı program içerisinde “section .data” bölümünde aşağıdaki gibi
tanımlanabilir.
pi equ 3.1416
4.1.2. section.bss
Bu bölümün adındaki bss ise Block Started by Symbol kısaltmasıdır. Bu tanımlamanın geçmişi 1950’li
yıllara dayanmaktadır. IBM 704 sistemi için Assembly dili geliştirildiğinde program içerisinde
tanımlanan ama değer ataması yapılmadığı sürece aktif olarak bellekte yer almayacak olan
değişkenleri tanımlayan kod bloğu olarak tasarlanmıştır. Burada yer alan değişkenler ancak bir değer
atanırsa işletim sisteminden bellek ayrılması istenmekte ve ayrılan bellek alanına değişkene atanmış
olan değeri yazılmaktadır. Bu bölümde tanımlanacak olan bir değişken aşağıdaki gibi yazılmalıdır.
değişken_adı veri_tipi sayı
Tipi Büyüklüğü Adı Buna göre word büyüklüğünde yirmi adet değişken
resb 8 bit Byte alabilecek ve adı “dizi1” olan bir dizi tanımlamak istersek
resw 16 bit Word aşağıdaki gibi belirtilmesi gereklidir.
resd 32 bit Double word
resg 64 bit Quadword dizi1 resw 20
4.1.3. section .text
Bu bölüm program kodunun yazıldığı bölümdür. Bölüm içerisindeki tüm komutlar bir asıl bölümden
başlamak durumunda olduğu için aşağıdaki şekilde tanımlanarak başlar.
global main
main:
Assembly diline ait olan kodların başladığı bölüm “main” adlı satırdan sonra başlamaktadır.
Bölümün başında belirtildiği gibi aslında bu bir etikettir. Burada etiketin sonunda “:” kullanılmasını
bir alışkanlık haline getirmeniz yararınızadır. Etiket tanımlayıp ardından”:” koyulmaz ise Assembler
programı burada işlemi kesecek ve hata mesajı döndürecektir.
Şimdi merhaba.asm programını satır-satır inceleyelim. Bu programda Assembly dilinin bellek
komutlarından “mov” kullanılmaktadır. Bu komut bir bellek alnında bir yazmaca veya bir yazmaçtan
bir bellek alanına veya ki yazmaç arasında veri aktarımı yapılması için kullanılır.
1. mov rax, 1 ile akümülatöre “1” ataması yapıldığında yazma sistem çağrısı aktif kılınmaktadır.
2. mov rdi, 1 ile “destinatoin index” atanan “1” sistem çağrısı ile standart çıktıya yazdırma işlemi
yapılacağı belirtilmiş olmaktadır.
3. mov rsi, msj ile msj adlı değişkenin bellekte bulunduğu adres bilgisi atanmaktadır.
4. mov rdx, 13 ile, mesajın uzunluğu belirtilmektedir. İlk karakterden başlayarak “byte
cinsinden” okunması gereken dizgenin karakter cinsinden büyüklüğü belirtilmektedir. Null
terminatör okunmasına veya hatta yazdırılmasına gerek olmadığı için büyüklüğünü belirtmek
yeterlidir.
5. syscall ile işletim sisteminin sistem çağrıları kullanılarak msj adlı değişkende barındırılan
dizge ekrana yani komut satırına yazdırılacaktır.
6. mov rax, 60 60 numaralı sistem çağrısı çağrılmaktadır. Bu sistem çağrısı programın
sonlandırılacağını belirtir.
7. mov rdi, 0 “0” çıkış kodu rdi yazmacına yüklenmekte ve ardından da sistem çağrısı ile
program sonlandırılmaktadır.
Böylece program sonlandırıldığında herhangi bir hata kodu veya mesajı döndürülmeden program akışı
sonlandırılmış olacaktır.
Sistem çağrıları, programların işletim sistemi tarafından belirli işlevleri yerine getirmesi için kullanılır
ve her işletim sistemi farklı sistem çağrılarına sahiptir. Programların 32 bit veya 64 bit mimarilere göre
yazılması, kullanılan sistem çağrılarının farklılık göstermesine neden olur. NASM ile oluşturulan bir
dosyanın içeriği, program kodunun nesne dosyasına dönüştürülmüş halini ve bellekteki konumlarını,
kullanılan yazmaçlar ile birlikte detaylandırır. Assembly ve makine dili arasındaki temel farklar,
okunabilirlik ve programlama dilinin nesil ayrımı üzerinedir.
Önemli Noktalar:
- **Sistem Çağrıları**: İşletim sistemi tarafından yerine getirilmesi için özel işlevler.
- **32 Bit ve 64 Bit Farkı**: Programlama mimarisi farklılıkları, sistem çağrılarını etkiler.
- **NASM Dosyası**: Program kodunun nesne dosyasına dönüştürülmüş halinin detayları.
- **Bellekteki Adresler ve Yazmaçlar**: Kodun bellekteki konumu ve kullanılan yazmaçlar.
- **Assembly ve Makine Dili**: Anımsatıcı komutlarla okunabilirlik ve nesil farklılıkları.