PIC Assembly - PIC C Assembly ve Emu8086 By Konuk Yazar Posted on 22 Aralık 2016 14 min read 0 2 10,596 Paylaş ! Facebook Paylaş ! Twitter Paylaş ! Google+ Paylaş ! Reddit Paylaş ! Pinterest Paylaş ! Linkedin Paylaş ! Tumblr Bu yazımda sizlere assembly dili hakkında bilgi vermeye çalışacağım. Bunu yaparken emu8086 emulatörü kullanacağım. Takdir edersiniz ki aslında çok uzun bir konu fakat ben elimden geldiği şekilde kısaltmaya ve önemli noktalarına değinmeye çalışacağım. Uzun bir yazı olacak bu yazımda Assembly dili avantajları ve dezavantajları, Genel amaçlı kullanılan registerlar, Segment Registerları ve Özel amaçlı registerlardan bahsedeceğim. Aşağıda bir 8086 mikroişlemcisi ve pinlerini gösteren bir görsel bulunmaktadır. Assembly dili düşük seviyeli bir dil olup program yazarken doğrudan bilgisayarın işlemcisi ve hafızası ile uğraştığınız için bilgisayarın donanımsal özelliklerini bilmeniz gerekir. Burada ortaya çıkaracağınız program kullanılan mikroişlemcinin yapısına bağlıdır. Assembly dilinin birçok avantajı vardır. Tabi bu avantajlarının yanında dezavantajları da bulunmaktadır. Hepsini saymayacağım fakat bir kaç avantajına değinmek istiyorum. İşlemcinin gücünü en iyi şekilde ortaya koyan tek programlama dilidir. İyi derecede assembly dili bilen bir kişi diğer dillerde karşılaştığı sorunları ve çözemediği sıkıntılı yerleri assembly ile rahatça çözebilir. Kaynak kodlarınızı paylaşıma açtığınızda eğer kodların yanlarına açıklama yazmamış ve uzun bir kod paylaşmış iseniz assembly bilmeyene birisinin o kodları anlaması imkânsızdır. Assembly bilen birinin ise o kodları çözebilmesi ise çok uzun zamanını alacaktır. Bunun sebebi assembly dilinin diğer dillere göre çok daha karmaşık olmasıdır. Dezavantaj olarak ise; Öğrenilmesi uzun sürer ve emek ister, üstünde sürekli çalışılması ve tekrar edilmesi gerekir. Yazdığınız kod mikroişlemci tipine göre değişiklik gösterir. Eğer programı Intel mikroişlemcide yazarsanız daha sonra bu programı Macintosh bilgisayarlarda kullanmaya çalışırsanız çalışmayacaktır. Program taşınabilir platforma bağımlıdır. Bu bilgilerden sonra Emu8086 kullanarak bir kaç program örneği yazacağım fakat bundan önce komutlar ve registerlar hakkında bilgi vermemin gerektiğini düşünüyorum. 8086 da CPU’nun içinde 8 adet genel amaçlı kullanılan register mevcuttur. AX: Accumulator register.(AH/AL olarak bölünmüştür) BX: Base register. (BH/BL olarak bölünmüştür) CX: Counter register. (CH/CL olarak bölünmüştür) DX: Data register. (DH/DL olarak bölünmüştür) Bu registerlar 16 bitlik registerlardır. Fakat parantez içinde belirtilmiş olanlar ise 8 bitlik registerlar olarak kullanılır. Bunlara ek olarak 32 bitlik, 64 bitlik, 128 bitlik registerlar mevcuttur. Burada Mov komutuyla( ikinci yazımda ne işe yaradığını anlatmaya çalışacağım) registerlara değer ataması yaptık. Mavi kutudaki değerler AH, BH, CH, DH olarak 8 bitlik değerlerdir. Yeşil kutudakiler ise AL, BL, CL, DL olarak 8 bitlik değerlerdir. AX,BX,CX,DX ise 16 bitlik değerlerdir. Mov AX, 3425H ile değer ataması yaptığımız zaman, Al registerı 25 değerini alırken Ah ise 34 değerini alır. Diğerleri içinde durum aynısıdır. SI: Source index registeri – Data segmentteki verileri göstermek için kullanılan bir index registerdır. DI: Destination index registeri – SI ile tamamen aynı özellikleri taşır. 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. Genel amaçlı kullanılan registerlardan sonra Segment Registerları vardır. Bunlar ise; CS: Code Segment – Programın bulunduğu bölümü işaretleme yapar. DS: Data Segment – Genellikle değişkenlerin tanımlandığı segmente işaret eder. ES: Extra Segment – Bu registerın kullanım amacını kullanıcı belirler. SS: Stack Segment – Stack bulunduğu yeri işaret eder. Segment registerlarda isterseniz veri depolama işlemi yapabilirsiniz fakat bu segment registerların asıl amacı değildir. Segment registerların memory de ulaşılabilir bölümleri işaretlemek amacıyla kullanılması daha sağlıklı olacaktır. Segment adresi: Herhangi bir 64 KB’lık hafıza bölümünün başlangıcını gösterir. Offset adresi: 64 KB’lık hafıza bölümünde herhangi bir satırı belirtir. Segment Register’ı 1000H değerinde olduğu zaman 10000H ile 1FFFFh aralığında bir hafıza adresine karşılık gelir ki bu da 64KB lık bir uzunluğa sahiptir. Ayrıca F000H’ın yer değiştirme adı verilen bir offset adresinin belekteki 1F00H konumunu nasıl seçtiğini gösterir. Başlangıç adresi belli ise, bitiş adresi FFFFH ilave edilerek bulunur. Çünkü segment register’ı 64KB’lık bir bölümü işaret eder. Offset adresi her zaman segment başlangıç adresine eklenir. Segment ve offset adresi bazen 2000:3000 olarak yazılabilir. Burada 2000H segment adresi, 3000H ise Offset adresi olur. Eğer Segment adresinde bir değişiklik yapılmaz ise 0700H default olarak kullanılır. Segment registerlardan sonra ise Özel amaçlı registerlar bulunur. IP: Instruction Pointer. Her zaman CS içinde işlenecek olan bir sonraki komutun yerini işaret eder. FLAGS REGISTER: CPU tarafından matematiksel işlemler sonucunda otomatik olarak değiştirilir. Bu register sayesinde, elde edilen sonucun çeşidi ve durumu ile ilgili bilgiler, program tarafından kullanılabilir. Genel olarak bu registerlara doğrudan erişemezsiniz. Burada da 9 adet flag biti bulunur. Bunları bilmeniz programı yazarken yararınıza olacaktır. Carry Flag (CF): Eğer bu flag 1 olursa unsigned overflow var demektir. Yani siz 255+1 byte yaparsanız sonucunuz 0…255 arasında olmadığı için flag 1 olacaktır. Hata durumunu göstericektir. Fakat böyle bir durum olamadığı zaman flag 0 olacaktır. Bu flag size toplama işleminde elde edilen carry veya çıkarma işleminden elde edilen odd değerini tutar. Parity Flag (PF): Bu flag bit sayısı çift olduğunda 1’e, bit tek sayı olduğunda 0’a ayarlanır. Sonuçta hiç 1 bit yok ise sayı çift parity e sahitir. Eğer sonuç kelime(Word) ise sadece 8 alt bit analiz edilir. Auxiliary Flag (AF): Düşük aralık (4 bit) için unsigned overflow olduğunda 1 olur. Zero Flag (ZF): Aritmetik veya mantık operasyonunun sonucu sıfır olduğunda flag 1 değerini alır. Sonuç sıfırdan farklı ise flag 0 degerini alır. Sign Flag (SF): Aritmetik veya mantık operasyonu sonucu negatif ise flag 1 değerini alır. Sonuç pozitif ise flag 0 değerini alır. Aslında bu bayrak most significant bit(MSB) değerini alır. Trap Flag (TF): Çip üzerinde debug yapmak için kullanılır. Interrupt enable Flag (IF): CPU harici bir aygıt tarafından gelen kesmelere tepki verir ve sonuçta flag 1 olur. Direction Flag (DF): DI ve/veya SI register’ları için arttırma veya azaltma modlarından birini seçer. Overflow Flag (OF): Unsigned overflow oldugu zaman flag 1 olur. Buna örnek vermek gerekirse. 100 + 50 byte ı toplarsanız 150byte elde edersiniz fakat bu değer -128…..127 arasında olmadığı için flag 1 olacaktır. Bu uzun yazıdan sonra ikinci yazımda sizlere adresleme modları hakkında bilgi verip birkaç C kodunu assembly koduna çevirmeyi anlatmaya çalışacağım. Kaynaklar The Microprocessor and Its Architecture, BIM303 Microcomputers 8086 KOMUT KÜMESİ ve ÖRNEKLER – Doç.Dr.M.Ali Akcayol http://w3.gazi.edu.tr/~akcayol/files/emu8086.pdf http://www.yecd.com/os/8086%20assembler%20tutorial%20for%20beginners%20(part%201).htm https://eclass.upatras.gr/modules/document/file.php/EE649/8086%20Registers.htm