Programlar Sabit diskte saklanır Sabit diskten veri okumak çok yava ş oldu ğ u için programlar çalı ş tırılmadan önce RAM’e yüklenir
İş lemci makine dili adı verilen komutları i ş letebilmektedir. Bu komutlar ile oldukça basit i ş lemler gerçekle ş tirilebilmektedir. Toplama, Çıkarma, Çarpma,vb. Makine komutları ikili sayı sistemi ile temsil edilmektedir.
İ kili sayı sistem ile program yazmak insanlar için oldukça zordur. Bunun yerine her bir makine komutuna sembolik bir isim verilerek ara bir dil olu ş turulmu ş tur Bu dile sembolik (Assembly) dil adı verilmi ş tir Assembly dilinde yazılmı ş bir kodu makine diline çeviren programa Assembler adı verilmektedir.
WindowsLinux
int sonuc = 0; int topla(int a,int b) { int t=a+b; sonuc+=t; return t; } gcc -O1 -fno-omit-frame-pointer -c 1.c 1.o Obje Kodu
Adres Makine Kodu 16 lık sistem (HEX) Assembly kod kar ş ılıkları
int sonuc = 0; int topla(int a,int b) { int t=a+b; sonuc+=t; if(t<10) t++; return t; } gcc -O1 -fno-omit-frame-pointer -S 1.c.file"1.c".text.globl_topla.def_topla;.scl 2;.type32;.endef _topla: LFB0:.cfi_startproc pushl%ebp.cfi_def_cfa_offset 8.cfi_offset 5, -8 movl%esp, %ebp.cfi_def_cfa_register 5 movl12(%ebp), %eax addl8(%ebp), %eax addl%eax, _sonuc cmpl$9, %eax jgL2 incl%eax L2: popl%ebp.cfi_def_cfa 4, 4.cfi_restore 5 ret.cfi_endproc LFE0:.globl_sonuc.bss.align 4 _sonuc:.space 4 1.s
.file"1.c".text.globl_topla.def_topla;.scl 2;.type32;.endef _topla: LFB0:.cfi_startproc pushl%ebp.cfi_def_cfa_offset 8.cfi_offset 5, -8 movl%esp, %ebp.cfi_def_cfa_register 5 movl12(%ebp), %eax addl8(%ebp), %eax addl%eax, _sonuc cmpl$9, %eax jgL2 incl%eax L2: popl%ebp.cfi_def_cfa 4, 4.cfi_restore 5 ret.cfi_endproc LFE0:.globl_sonuc.bss.align 4 _sonuc:.space 4
.file"1.c".text.globl_topla.def_topla;.scl 2;.type32;.endef _topla: LFB0:.cfi_startproc pushl%ebp.cfi_def_cfa_offset 8.cfi_offset 5, -8 movl%esp, %ebp.cfi_def_cfa_register 5 movl12(%ebp), %eax addl8(%ebp), %eax addl%eax, _sonuc cmpl$9, %eax jgL2 incl%eax L2: popl%ebp.cfi_def_cfa 4, 4.cfi_restore 5 ret.cfi_endproc LFE0:.globl_sonuc.bss.align 4 _sonuc:.space 4.file"1.c".text.globl_topla.def_topla;.scl 2;.type32;.endef _topla: LFB0: pushl%ebp movl%esp, %ebp movl12(%ebp), %eax addl8(%ebp), %eax addl%eax, _sonuc cmpl$9, %eax jgL2 incl%eax L2: popl%ebp ret LFE0:.globl_sonuc.bss.align 4 _sonuc:.space 4
movl $0x4050,%eax Immediate--Register, 4 bayt eax’e 0x4050 değeri yüklenir movw %bp,%sp Register--Register, 2 bayt bp’nin değeri sp’e yüklenir. movb (%edi,%ecx),%ah Memory--Register, 1 bayt edi+ecx adresindeki veri ah’a yüklenir. movb $-17,(%esp) Immediate--Memory, 1 bayt esp’nin gösterdiği adrese -17 değeri yazılır movl %eax,-12(%ebp) Register--Memory, 4 bayt ebp-12 adresine eax’ın değeri yazılır.
Başlangıçta %dh = CD, %eax = değerlerine sahip olsun movb %dh,%al %eax = CD sadece veri taşıması yapılıyor. movsbl %dh,%eax %eax = FFFFFFCD eax’in ilk 8 baytı dh’ın değerini alırken kalanını dh’ın ilk bit değeri ile dolduruyor. movzbl %dh,%eax %eax = CD eax’in ilk 8 baytı dh’ın değerini alırken kalanını 0 ile dolduruyor.
A ş a ğ ıdaki komutların sonuna uygun harfleri yazınız. (Örne ğ in mov yerine movb,movw,movl)
A ş a ğ ıdaki assembly satırlarından hangisi hatalı yazılmı ş tır
Adres bilgisini registerlara kopyalamak için kullanılır. A ş a ğ ıdaki komuttan önce edx a de ğ erine sahip oldu ğ unu dü ş ünürsek eax’in sahip olaca ğ ı de ğ er 5a+7 olacaktır. Derleyiciler leal komutunu adres yükleme ile alakası olmayan bir çok i ş lem için kullanabilmektedir. leal 7(%edx,%edx,4), %eax
edx de ğ erlerini bulunuz.
Çarpam ve bölme i ş lemleri i ş aretli(signed) ve i ş aretsiz(unsigned) sayı türleri üzerine yapılabilmektedir. Çarma i ş lemi ile 32 bitlik iki sayı çarpılıp sonuç olarak 64 bitlik bir sayı elde edilir. Mul komutuna verilen register ile eax registerındaki de ğ er çarpılır. Sonuç edx:eax registerlarının birle ş tirilmesiyle elde edilir.
X ve Y de ğ i ş kenleri ebp+8 ve ebp+12 adreslerinde bulunsun. Bu iki sayıyı çarpıp sonucu esp+4 adresine yazıyoruz. Makinemizin little-endian oldu ğ una dikkat etmeliyiz.
Bölme i ş lemi 64 bitlik bir sayının 32 bitlik bir sayıya bölünmesiyle elde edilir. Bölme i ş leminde edx:eax registerları istenilen registera bölünür. Bölüm eax kalan edx içerisine yerle ş tirilir.
Fonksiyon ça ğ ırma i ş lemi için call komutu kullanılır. Fonksiyon parametreleri call komutu ile yollanamaz. Bu sebeple fonksiyona ait parametreler, fonksiyon ça ğ rılmadan önce programa ait olan yı ğ ına yerle ş tirilir. Fonksiyon gövdesinde ilk olarak parametreler yı ğ ından sırası ile alınır.
Yı ğ ın hafızada a ş a ğ ı do ğ ru büyür. Her bir fonksiyon yı ğ ın içerisinde bir alana sahiptir. Bu alana yı ğ ın çerçevesi (stack frame) adı verilir. Fonksiyon sonlandı ğ ında yı ğ ın çerçevesi de sisteme iade edilir. Yı ğ ın çerçevesinde yerel de ğ i ş kenler ve parametreler saklanmaktadır. Yı ğ ında en son yazılan adresi gösteren register’a esp adı verilir.
_topla: LFB0: pushl %ebp movl %esp, %ebp movl 12(%ebp), %eax addl 8(%ebp), %eax addl %eax, _sonuc popl %ebp ret LFE0:.def ___main;.scl 2;.type 32;.endef.globl _main.def _main;.scl 2;.type 32;.endef _main: LFB1: pushl %ebp movl %esp, %ebp andl $-16, %esp subl $16, %esp call ___main movl $4, 4(%esp) movl $3, (%esp) call _topla leave ret int sonuc = 0; int topla(int a,int b) { int t=a+b; sonuc+=t; return t; } int main() { topla(3,4); } 2.c 2.s İ kinci parametre yükleniyor İ lk parametre yükleniyor
call komutu ça ğ rılacak fonksiyonun adresine ihtiyaç duymaktadır. Ça ğ rılan fonksiyonun i ş lemi bittikten sonra i ş lemcinin programa kaldı ğ ı yerden devam edebilmesi gerekir. Bu yüzden call komutu fonksiyonu ça ğ ırmadan önce kendisinden sonra gelen komutun adresini yı ğ ına yükler. Bu sayede ça ğ rılan fonksiyon i ş lemi bittikten sonra ret komutunu ça ğ ırarak i ş lemciyi bu adrese yönlendirebilir. eip çalı ş tırılacak olan sıradaki komutun adresini tutmaktadır.
Registerlar bütün fonksiyonlar tarafından payla ş ılmaktadır. Bir fonksiyon ba ş ka bir fonksiyonu ça ğ ırdı ğ ında ça ğ rılan fonksiyon ça ğ ıran fonksiyonun önemli de ğ erler sakladı ğ ı registerları de ğ i ş tirebilir. Böyle bir problem olu ş maması için ça ğ ıran ve ça ğ rılan belirli registerları yı ğ ında saklarlar. eax,ecx,edx registerları ça ğ ıran fonksiyon tarafından saklanır ebx,esi,edi registerları ise ça ğ rılan fonksiyon tarafından saklanır.
P fonksiyonu Y de ğ i ş keni için ebx registerını Kullanaca ğ ından ebx yı ğ ına yedekleniyor. Y de ğ i ş keni için ebx registerını Kullanaca ğ ından ebx yı ğ ına yedekleniyor. Yı ğ ındaki eski y de ğ eri fonksiyon bitmeden Hemen önce tekrardan registera yerle ş tiriliyor. Yı ğ ındaki eski y de ğ eri fonksiyon bitmeden Hemen önce tekrardan registera yerle ş tiriliyor. 3.c 3.s
Programlar çalı ş tı ğ ında sahip oldukları kodlar sıra ile i ş letiliyor. jmp türü komutlar ile akı ş ın sırası de ğ i ş tirilebilmektedir. jmp hiçbir ko ş ul olmadan EIP’nin istenilen adrese gitmesini sa ğ lamaktadır. EIP
jmp ko ş ulsuz atlama yaparken çe ş itli ş artların olu ş ması durumunda atlama yapan komutlarda mevcuttur. Bu komutlar bayrak registerında bulunan bitlerin de ğ erlerine göre atma yapmaktadır. Bayrak registerının her bir biti ayrı ayrı isimlendirilmi ş tir. Biz bunlardan 4 bit üzerinde duraca ğ ız CF (Carry Flag- Elde bayra ğ ı ):Son yapılan i ş lemin sonucunda elde edilirse bu bite 1 atanır. ZF(Zero Flag-Sıfır bayra ğ ı): Son yapılan i ş lemin sonucunda 0 çıkarsa bu bite 1 atanır. ZF(Sign Flag – İş aret bayra ğ ı) : Son yapılan i ş lemin sonucunda negatif bir sayı çıkarsa bu bite 1 atanır. OF(Overflow Flag-Ta ş ma bayra ğ ı) :Son yapılan i ş lemin sonucunda elde edilirse bu bite 1 atanır. Negatif veya pozitif ta ş ma olabilir.
3.c 3.s
2.satırdaki jmp komutu.L1 adresine atlama yaptıracaktır. Bu yüzden 3. satırdaki komut asla i ş letilemeyecektir.
Assembly kar ş ılı ğ ı sa ğ da verilmi ş olan C programının bo ş luklarını doldurunuz.
C programındaki de ğ i ş kenlerin hangi registerlar tarafından kullanıldı ğ ını bulunuz?