[ASM]Assembly Giriş

  • Konbuyu başlatan Konbuyu başlatan sec0nd
  • Başlangıç tarihi Başlangıç tarihi
Konu Yazar

sec0nd

New Member
Kalemi Kırıldı!
Haz
235
1
Merhabalar,

Öncelikle Bu programlama dilini paylaşacağım bir bölüm olmadığı için buraya açmaya gerek duydum eğer başka yere ise düzeltilmesi adminlerden ricamdır.

Son zamanlarda merak saldığım ve soacs gibi oyun güvenlik sistemlerininde kullandığı bu programlama dilini size biraz anlatıcam.

ASSEMBLY PROGRAMLAMA DİLİ (BÖLÜM-1)

GİRİŞ :

Evet arkadaşlar Bismillah diyerek başlıyoruz. Ko-Cuce için yazdığım bu makaleyi Assembly dilini çok iyi bilen biri olarak DEĞİL , ÖĞRENEN biri olarak anlattım ve mümkün olduğu kadar açıklayıcı ve basite indirgemiş şekilde anlatmaya çalıştım, çünkü bu makaleyi programlamayla iyi bir şekilde uğraşan arkadaşlar la beraber programlamayla amatör şekilde uğraşan arkadaşlarımız da okuyacaktır.Bu nedenle oldukça basit bir şekilde anlatım yaptığıma inanıyorum.Aynı zamanda hiç programlama bilgisi olmayan arkadaşlarda bu yazıyı okuyacaklardır ,fakat “Bu da ne böyle ,bu nasıl dildir”diyeceklerine de eminim  Ama tekrar yapılarak ve azimle onlarında öğreneceğinden eminim.Bu makalenin sonunda uzman bir assembler programcısı olacağınızı elbette ki söyleyemem ,fakat assembly hakkında çok şey öğreneceğinizden de eminim.Assembly biraz karmaşık gibi görünebilir,çünkü makinenizin yani bilgisayarınızın anladığı asıl dil bu diyebiliriz.Diyebiliriz diyorum çünkü aslında CPU yani işlemciniz Binary sayılar dediğimiz ikili sayı ( 1 ve 0 ) sisteminden başka bir dilden anlamaz.Bu sayıları ve dönüşümlerini ileriki konularda anlatacağım zaten bu nedenle üstünde durmuyorum.
Aslında üst düzey hangi programlama dilini kullanırsanız kullanın ,hepside sonunda kullandığınız prog.dilinin compiler’i (derleyici) tarafından makine diline çevrilir. Yani 1ve 0 (sıfır)’ lara .1’in mantığına “akım var”, 0 ‘ın mantığı’na da “akım yok” diyebiliriz,kısaca makine bu dilden anlar, ve yine kısaca makineler aptaldır ama çok seri ve hızlıdırlar diyebiliriz. O zaman neden assembly öğrenmeyesiniz ki? Evet dersimize geçiyoruz .

ASCII :

Arkadaşlar bir byte ile temsil edilen harfler için kullanılan en yaygın ASCII (Ameri can Standard Code for Infırmation Interchange) kod standardıdır. Herhangi bir *.exe dosyasına debugger (editor) ile baktığınız zaman ,o dosyanın içerisinde bir çok karmakarışık semboller ,işaretler ve karakterler görürsünüz.Bunlar Ascii kod karakter setinde ki rakamlara karşılık gelen harfler veya sembollerdir.Ascii tüm ülkelerde standart hale getirilmiş kod setleri olup,sizin kullandığınız bilgisayarlarda ve cep telefonlarında da bu standart kodlar kullanılır.Bu kodlar 0-255 arası değişik karakterlere ,harflere ve sayılara sahiptir.Mesela bizim kullandığımız 1 rakamını karşılığı Ascii 33 ‘tür.Büyük harfler 65 ‘den başlar ,küçük harflerde 97 ‘den başlayıp 122 ‘ye kadar devam eder.Aşağıda ki,

Sayılar: Harfler:
32=0 65=A 97=a
33=1 66=B 98=b
34=2 67=C 99 =c
35=3 68=D 122=z

gibi örnekler verebiliriz.Bunların dışında kalan karakterler ise değişik sembolleri ( ?,*,-,!,é,+) ve sesleri(Beep sesi mesela) ve ayrıca satır başı,boşluk karakteri gibi işlerin karşılığıdır.

BINARY (İKİLİ SAYI SİSTEMLERİ ) :

Arkadaşlar yazıya başlarken makinelerin aslında 1 ve 0 (sıfır) dan başka bir şeyi anlamadığını söylemiştik.Çünkü makineler devrelerinde akım geçer veya geçmez mantığını kullanır.Dolayısıyla 1 için “akım vardır”,0 içinse “akım yoktur” deriz.Veya 1 için Açık,0 için Kapalı diyebiliriz.İşte bu 1 ve 0 ların her birine bit ,bu bitlerin 8 tanesinin bir araya gelip oluşturdukları gruba da bayt diyoruz arkadaşlar.Görüldüğü gibi 1 ve 0 dan oluşan sadece 2 tane sayımız var ,işte bu nedenle bu sayılara da Binary (ikili sayılar) deniyor.CPU da yani mikro işlemcide birçok işlemlerini bu bitler üzerinde yapar.Bu kısa tarifleri yeterli bularak bunlarla yapılan işlemlere geçiyorum.
Binary sayılar 0-255 arası değer alırlar.
00000000=0 11111111=255

(Ascii değer de 255 değer alıyordu)

8 tane bit bir araya gelip 1 baytı oluşturuyor demiştik yukarıda ,eğer bunlar işaretli bir sayı olacak olsaydı o zamanda –(eksi) 127 ile + 128 arasında değer alacaklardı bi nevi ikiye bölünmüş olacaktı..2 Byte lık yani 16 bitlik(word) sayının alacağı değer normal de 65535 tir.Negatif bir sayı alması durumunda ise bir yarısı -32768 ile diğer yarısı +32767 arasında olur,bunların nasıl bu değerleri aldığını görelim.Lutfen burayı iyi takip edin çünkü sayı sistemlerin de Binary sayı mantığını anlamanız size çok büyük kolaylıklar sağlayacak.

1-) 1-1-1-1-1-1-1-1 daima hesaplamaya sağdan başlıyoruz aynen onluk düzende olduğu gibi;
1*1 - 1*2 – 1*4 – 1*8 – 1*16 – 1*32 – 1*64 – 1*128
2 ve 2 nin katları şeklinde hesaplıyoruz
1+2+4+8+16+32+64+128 = 255
Çarpım sonuçlarını sadeleştiriyor ve topluyoruz sonuç =255
Not: Unutmadan söyleyeyim sağdaki ilk rakamı hep 1 ile çarparız daha sonra kullanılan sayı sisteminin katları ile çarparız.Bu Onluk düzende de,Onaltılık düzende de aynıdır,değişmez.Mesela Onluk düzen hep şu şekilde gider 1-10-100-1000- 10000 gibi 10 sayısının katları şeklinde ilerler.İkilik düzende de aynıdır yani; 1-2-4-8-16-32 gibi 2 ve 2 ‘nin katları şeklinde gider.

2-) Peki şöyle bir şey olsaydı 00101100 yine aynı işleme tabi tutardık elbette , evet yapalım ;
Dikkat sayının sağından başlıyorum
0*1- 0*2 - 1*4 -1*8 - 0*16 - 1*32
diğer sıfırları çarpmaya gerek yok çünkü sonuç sıfır olacaktır.
0 + 0 + 4 + 8 + 0 +32 = 44
sadeleştirip topladık sonuç = 44.
Anlaşılması açısından 0*1 ve 0*2 yi ekledim yoksa bunları katmadan çıkan sonuçları toplayıp sonucu bulabilirsiniz.

Onluk Sayıyı Binary’e Çevirme :

Evet arkadaşlar bunuda hemen bir örnekle anlatmadan önce şunu hatırlatayım ,sayımız zaten 1 ve 0 dan oluşuyor onun için bu sayıyı 2 ye böleceğiz ve bunu bulmak çok kolay olacak Ayrıca bir hatırlatma eğer tam bölünme oluyorsa 0 ,kalanlı bölünüyorsa 1 olarak yazılır çünkü bir sayı 2 ye ya tam bölünür yada kalanlı bölünür.Yukarıdaki sayımızın Binary karşılığını bulalım yani 44 sayının.
44 / 2 0
22 / 2 0
11 / 2 1
5 / 2 1
2 / 2 0
1 / 1 1 Kalan 1 sayısı aynen alınır.

Bu sayıyı ters çevirip aldığımızda 101100 böyle bir sayı çıkar.Bunu yukarıda göstermiş olduğum şekilde hesaplarsanız sağlamasını da yapmış olacaksınız.Başka bir örnek;
23 /2 1
11 /2 1
5 /2 1
2 /2 0
1 /1 1 Kalan 1 sayısı aynen alıyoruz çünkü 2 ye bölemeyiz.
Bu sayıyı ters çevirip aldığımızda 10111 böyle bir sayı çıkar ki bunu da 1+2+4+0+16= 23 bu şekil de topladığınız zaman sonucun 23 olduğunu göreceksiniz.

ONLUK SAYILAR (DECIMAL) :

Bu sayı sistemini aslında hepimiz biliyoruz arkadaşlar.Gündelik yaşantımızda ,okulda, işte kısaca her yerde kullandığımız sayı düzeni.Ama ikili sayı sisteminin anlaşılması açısından kısaca bu sayı sistemine değinerek geçeceğim.Bu sayılarda kendi arasında 10 ve 10’un katları şeklin de ilerler.
8452 sayısını ele alalım bu sayıda ne var?Aslında hiçbir şey yok normal bir sayı zatenAnaliz edelim hemen ;
Sağdan başlıyoruz : 2 tane 1 var,5 tane 10 ,4 tane 100 ,8 tane 1000 var.Dikkat ettiniz mi; 1-10-100-ve 1000 diye gittik.Yani 2*1 + 5*10 + 4*100 + 8*1000 =8452 umarım ikilik sayı düzeni bu örnekle daha iyi anlaşılır.

ONALTILIK SAYILAR ( HEXDECİMAL ):

Bunu aşağıdaki gibi örnekle açıklayalım bir .exe dosyasına baktığımız zaman A harfinin karşılığını 65 değerinde değil de, 41 değerinde görürüz.Halbuki A ‘nın Ascii kod karşılığı 65 di.Peki bu neden böyle oluyor?

res1du3.jpg


Bunun nedeni arkadaşlar bilgisayarın ilk çıktığı dönemlerde programcılar Binary kodlarla (ikili sayılar) çalışmak zorundaydılar.Çünkü bilgisayar bu dilden başka bir dil anlamıyordu.Düşünün bir kere 11001010 gibi bir sayı sistemi ile ne şekilde çalışabilir ve hatasız bir kod nasıl çıkarabilirsiniz.İşte bu durum da program uzmanları ortaya bir buluş atmışlar . Bildiğiniz gibi, dört bit ikilik değerleri 0000 ile 1111 arasında (ondalık 0 ile 15 değerleri arasına eşittir), 16 olası kombinasyonun bir toplamı olarak gösterir. Eğer sayma sistemi bu 16 kombinasyonda gösterirse, 16 rakama sahip olmalıdır. Bu da bir “taban 16 sistemi” olmalı.Bu durumda programcılar bir nebze olsun daha rahat çalışsın diye bu sayı sistemini geliştirmiş ve adına Yunan sözcüğü olan “hex” (6 için) ile bir Latin sözcüğü olan “decem” (10 için) birleşimiyle oluşan “hexdecimal – (hexdesimal)” ismiyle isimlendirmişler. Bu sayede taban 16 sistemine “hexadesimal” (onaltılı) sayı sistemi dendi.
Böylece 1 ve 0 dünyasından kendilerini kurtarmış oldular .Dikkat edin kendilerini kurtarmışlar bilgisayarı değil.Dedik ya makineler sadece 1 ve 0 ‘ı anlar diye.
İşte yukarıdaki resimde gördüğünüz 41 sayısıda “A” harfinin 16 lık sayı sistemindeki karşılığıdır.Böylece kodlar 2 sıralı halde ve düzgün bir görünüme kavuşuyor.
ASSEMBLY ise Binary sayılarla olsun,Hexdecimal sayılar olsun bunların tümünün ,CPU yu görevlendirmek için oluşturdukları sayısal komutların sembolik karşılığıdır diyebiliriz.Çünkü her ne komut verirseniz verin bunların tamamı CPU ya bir sayısal değer olarak (1,0)gidecektir.
Onaltılık sayı tablosu

Hexadesimal Rakam BinaryDeğeri Ondalık Değeri
0 0000 0
1 0001 1
2 0010 2
3 0011 3
4 0100 4
5 0101 5
6 0110 6
7 0111 7
8 1000 8
9 1001 9
A 1010 10
B 1011 11
C 1100 12
D 1101 13
E 1110 14
F 1111 15


Tabloda gördüğünüz gibi 1,2,3,4,5,6,7,8,9 ‘dan sonra A,B,C,D,E,F,10,11,12 diye devam ediyor.Onluk düzende bildiğimiz sayılarla hemen hemen aynı sadece araya 6 tane harf girmiş. Burada görüldüğü gibi onaltılık sistem her 16 sayı sonrası basamak atlatıyor. Ayrıca a,b,c,d,e,f olmak üzere 6 tane daha fazladan sayıya sahip. O zaman onaltılık bir sistemde değer 10 ise onluk sistemde o sayı 16 demektir. Yani 16 nın katları olarak artmaktadır.Kafanız karışmasın hemen bir örnekle gösterelim.

0Fh = 15
10h = 16
20h = 32
30h = 48
F4h = 244
Açıkladığım gibi bu sayılarda 16 ve 16’nın katları şeklinde ilerliyor ,tıpkı Onluk düzende 10 ve 10 ‘un katları şeklinde ilerlediği gibi.Yukarıdaki örnekte dikkatinizi çektiyse ,soldaki rakamların sonunda küçük “h” harfi var.Bunu hesaplamalarda dikkate almayın sadece o sayının Hexdecimal bir sayı olduğunu gösteriri ki CPU bu sayıyı onluk düzendeki bir sayı gibi algılamasın.Normalde bundan sonra bu “h” harfini kullanacağımız için bu ne demek oluyor diye takılmayın. Assembler programlarında kullanılan sayılar şu şekillerde simgelenerek birbirinden ayrılırlar:

1010b sonundaki “b” harfi Binary sayı olduğunu;
2359d sonundaki “d” harfi Decimal yani onluk bir sayı oldugunu
4FA1h sonundaki “h” harfi HexDecimal yani Onaltılık bir sayı olduğunu gösterir.

- ’d’ harfi yada harfsiz bu bildiğimiz onluk sistemde demektir. Eğer bir kaynak kodunda sayının yanında (önceden bütün sayıların hex olacağını belirten .radix16 gibi bir komut kullanılmamışsa) hiçbir simge yoksa o sayı göründüğü değerinde bildiğimiz onluk tabanda bir sayıdır. Ama eğer onaltılık kurallarıyla yazılmış (a,b,c,d,e,f içerikli) ve yanında hiçbir işaret yoksa derleyici burada ’illegal number’ şeklinde bir hata mesajı verir.
Şimdiye kadar görmüş olduğumuz sayı sistemlerini kısaca hatırlayalım;

1-Binary (ikilik) Sayı sistemleri
2-Onluk (Decimal)Sayı sistemleri ve
3-Onaltılık (Hexdecimal) Sayı sistemleri.

Öncelikle şunu belirtmem gerekiyor arkadaşlar ; onluk zaten biliyoruz ama onaltılık ve ikilik sistem mutlaka bilinmesi gerekiyor. Programlarınızda, denemelerinizde hep bu sistemler kullanılacak. Komutlar hep bu sistemlere göre çalışacak ve bazıları sadece bu sistemlerdeki değerlere göre hareket edecek. Bunun için bir assembler programcısının mutlaka bu sistemleri bilmesi ve kullanması gerekiyor.Aşağıdaki konuyla bu konuları daha iyi bir şekilde pekiştirip bitireceğiz…


Onaltılık Sayıyı Onluk Sayıya Çevirme :

Arkadaşlar Onaltılık (Hexdecimal) bir sayıyı ,Onluk (Decimal ) bir sayıya 2 şekilde çevirebiliriz.
1.olarak aşağıda anlattığım şekilde çevirebilirsiniz.
2.olarak da bununla kim uğraşır diyerek, Windows ’un hesap makinesini kullanıp çevirebilirsiniz 
Ben yine de 1. olarak bahsettiğim şekliyle açıklayayım..Arkadaşlar yukarılarda ikili ve onlu sayı sistemlerini anlatırken birinci basamak her zaman kendi değerindedir demiştik.Burda da aynı kural geçerli yani sayı 0ah,0bh,0ch.. olsa bile onluk sisteme çevirilince birlik basamak olarak diğerlerine eklenir. Diğer basamaklarda aynı bildiğimiz matematik kurallarında olduğu gibi basamak çarpanı esas alınarak çarpılır. Nasıl ki 8452 sayısının 8*1000+4*100+5*10+2*1 olduğunu biliyorsak onaltılık sistemde de bu kuralın böyle olduğunu biliriz.Kısa bir örnekle acıklayalım;
FA5h sayısını ele alalım ve analiz edelim.Burda ilk önce 5 sayısını 1 le ,A’nın (Onaltılık sistemde) sahip olduğu değeri 16 ile , F’nin (Onaltılık sistemde) sahip olduğu değeri de 16 ‘nın bir sonraki katı ile yani 256 ile çarpacağız.Devam edelim,
Sağdan başlayarak yapıyorum yine ;
5*1 + A*16 + F*256 şimdi A ile F nin yerlerine Hexdecimal değerleri koyalım
5*1 + 10*16 + 15*256
Yukarıda ki tabloda A’nın hex karşılığını 10 , F nin hexdec.karşılığını ise 15 olarak göstermiştik.Sonuçları toplayalım o zaman ,
5 +160 + 3840 = 4005 olarak sonucu bulmuş oluruz.Biraz zor gibi görünebilir ama ben mümkün olduğu kadar sadeleştirip anlattım.Zaten 1 veya 2 deneme yaparsanız mantığı kavrarsınız arkadaşlar.Aşağıdaki katlara bakınca daha iyi anlayacağınızı ümit ediyorum….
Onluk Sistem : Onaltılık Sistem :
1 1
10 16
100 256
1000 4096
10000 65535
Gördüğünüz gibi 4005 gibi Onluk düzendeki büyük bir değeri Onaltılık sayı sistemine göre sadece FA5 diyerek gösteriyoruz.Bunun bize ne kadar büyük bir kolaylık getirdiğini ve Hexdecimal sayıların neden kullanıldığını anlamış olduğunuz kanaatindeyim.
Buraya kadar anlattığım yerleri eğer anlamak ta güçlük çekiyorsanız ; tekrar bu makaleyi baştan okumanızı tavsiye ederim çünkü gerçekten okudukça kolay olduğunu göreceksiniz,ama yok eğer buraya kadar anlatılanlardan bir harf dahi anlamadım diyorsanız,size buradan itibaren bırakmanızı tavsiye ederim çünkü bundan sonraki Registerler ve Komutların çalışma prensibini anlamak ta çok daha zorlanırsınız.Bilen ve bunlar çocuk oyuncağı diyen arkadaşlar varsa da onlar için devam edeceğim.Bir sonraki konularımız Registerler ve Komutlar.
 
Cevap: [ASM]Assembly Giriş

ASSEMBLY PROGRAMLAMA DİLİ (BÖLÜM -2 )



REGISTERLER :

Evet arkadaşlar geldik registerler (Namı diğer Yazmaçlar nedense bu kelimeyi görünce sinir oluyorum ben buna kaydedici demeyi uygun buluyorum ama bilmeniz açısından yazdım ) konusuna, bu konuda oldukça kolay arkadaşlar.Makaleyi okudukta sonra anlayacağınızdan eminim.Registerleri kısaca şöyle tarif edebiliriz, programlamayla ilgilenen arkadaşlar bilirler,hani program yazarken değişken dediğimiz ,(a=53 , b= ”atmaca” gibi)değer atama durumları vardır ya hani,işte registerleri de bu değişkenlere benzetebiliriz.Örneğin b=”atmaca” değişkenimize başka herhangi bir değer atamadığınız sürece “b” ‘nin değeri hep “atmaca olacaktır.Taki bir değer atarsanız ,mesela 42 derseniz o zaman “b” ‘nin taşıdığı değer 42 olur.Bunun gibi registerler de (yani kaydediciler) CPU’ nun her türlü işlemlerini yerine getirmesi için bu görevi yerine getirirler.
Kısaca şöyle de diyebiliriz ,işlemci yani CPU register adı verilen bölmelerden oluşur ve bu registerler de mikroişlemcinin en temel bileşenlerinden biridir .Bu registerleri ben 4 bölüme ayırmayı uygun buluyorum kimileri 3 yada 5 bölüm olarak inceleyebiliyor.

1-GENEL AMAÇLI REGİSTERLER
AX = Accumulator Register
BX = Base (Taban )Register
CX = Counter (Sayaç )Register
DX = Data (Veri )Register
2-SEGMENT REGİSTERLERİ
CS = Code Segment Register
DS = Data Segment Register
SS = Stack Segment Register
ES = Extra Segment Register
3-OFFSET REGİTERLERİ
IP = Instraction Pointer Register
SP = Stack Pointer Register
BP = Base Pointer Register
a-)İndex Registerler

SI = Source (Kaynak )Index Register
DI = Destination (Hedef)Index Register

4-FLAG (BAYRAK )REGİSTERLERİ
O = Overflow flag
D = Direction flag
I = Interrupt flag
T = Trace flag
S = Sign flag
Z = Zero flag
A = Auxilary Carry flag
P = Parity flag
C = Carry flag


Evet registerlerimiz bunlar,siz şimdilik hepsini de ezberlemeye kalkmayın zamanla programlar üzerinde durdukça öğreneceksiniz,bunlardan özellikle flag (bayrak )registerleri sadece bilgi almak açısından kullanırız ,yoksa bunlar üzerinde işlem yapamayız.İşlem sonunda eşitlik var mı yok mu,veya işlem sonunda taşma oluyor mu ya da olmuyor mu; gibi bilgileri görmek için kullanırız.Ben yine de mümkün olduğu kadar karşılarına Türkçe karşılıklarını da yazdım ki zorlanmayasınız.Bunların bir kısmını ayrıntılı olarak sonraki konularda anlatacağım zaten.

1-GENEL AMAÇLI REGİSTERLER :

Yukarıda görmüş olduğunuz (ax ,bx ,cx ve dx )registerleri eski 8 ve 16 bit işlemciler ( 8086,80186 gibi) için bu şekilde kullanılıyordu.Fakat bu işlemciler günümüzde pek kalmadı ve yeni 32 bit işlemciler daha yaygın bir şekilde kullanılıyor.Bunun içinde bu register isimlerinin başına Extended (Genişletilmiş ) kelimesinin “e” harfi getirildi.Yani EAX-EBX-ECX-EDX şeklinde oldular.Bizde bundan sonra bu Genel Registerler ,Segment Registerler ,Ofset ve İndex registerleri yazarken bu şekildeyazacağız.EBX-EDI-ESI-ESP vs gibi..
Bir ornek ;

Mov eax,24
Mov ebx, 10
Add eax , ebx
Sonuç = 34

Dönelim bu genel kaydedicilere ,bunlar kendi aralarında 2’ye bölünerek 8 adet olurlar.Şöyle ki;

EAX = AH - AL
(32 BİT)= (16 BİT) - (16 BİT)
EBX = BH - BL
(32 BİT)= (16 BİT) - (16 BİT)
ECX = CH - CL
(32 BİT)= (16 BİT) - (16 BİT)
EDX = DH - DL

Eğer bunlar 16 bit lik registerler olsaydı o zaman da 8 bit AH , 8 bit AL olarak değişecekti.Sonlarına eklenen H ve L harfleri “H” High (Yüksek)- “L” ise Low (Düşük) kelimelerinden gelmiştir. 16 bitlik bir register en fazla 65535 değerini alırken 32 bitlik bir register 4294836225 değerine kadar alır.

EAX register programlarda en çok kullanılan yazmaçlardan biridir. Accumulator’ün kısaltılması sonunda oluşan EAX yazmacı bütün giriş ve çıkış işlemlerinde ve bazı aritmetik işlemlerde kullanılır.

EBX Registeri Base register olarak da bilinir. RAM işlemlerinde adreslemede kullanılır. Register adresleme işlemlerinde daha çok offset degerlerini tutar. Ayrıca hesaplama işlemlerinde de kullanılır.

ECX Registeri Counter registeridir. Döngü işlemlerinde ve kaydırma işlemlerinde sayaç olarak kullanılırız.

EDX Register bazı giriş çıkış işlemlerinde ve matematiksel işlemlerde kullanılır.Daha çok çarpma ve bölme işlemlerinde büyük sayıları saklamak için AX registerinin bir parçasıymış gibi kullanılır.

2-SEGMENT REGİSTERLERİ :

Segment register’ ları (ECS, EDS, ESS ve ES) programımız bilgisayarın belleğine yüklendiği
zaman bellek içerisinde oluşturulan bölümlerin (Segment) başlangıç adreslerini tutarlar. Yani bu register’lar için bir çeşit yer göstergeci diyebiliriz. ECS, programımızın çalıştırılabilir kodlarını barındıran (Code Segment) bölgesinin başlangıç adresini tutar. Yani ECS ile gösterilen yerde makine dili kodlarımız vardır. EDS ise, programımız içerisindeki değişkenlerin saklı tutulduğu bölümdür. ESS (Stack), bellekte programımız için ayrılan stack bölümünün ( ki bu bölümü ayrı bir şekilde aşağıda anlatacağım ) başlangıç adresini tutar.ES (Extra segment) ise daha çok dizi yani string (Numerik olmayan) işlemleri için kullanılırız.

3-OFFSET VE İNDEX REGİTERLERİ :

Offset ve index register’ları bellek içerisindeki herhangi bir noktaya erişim sağlamak için kullanılır.Bu işlem için erişmek istediğimiz bölgenin offset ve segment adresleri gerekli register’lara aktarılır bizde bu şekilde işlemi gerçekleştirmiş oluruz..
Instruction Pointer register’ı ise CPU tarafından işlenecek olan bir sonraki komutun bellekteki adresini tutar. Bu register üzerinde programcının hiçbir eylemi olamaz. Her komut icra edildikten sonra CPU otomatik olarak kullanılan komuta göre gerekli değeri bu register’a atar.Arkadaşlar belki biraz ağır bir anlatım gibi görünebilir fakat bunların başka bir izah şeklini bulamadım yani şu an aklıma gelmiyor.

4-FLAG (BAYRAK )REGİSTERLERİ :

Arkadaşlar bunları detaylı bir şekilde anlatmadan önce şunu hatırlatmak istiyorum.Bayrak kaydedicisindeki her bir bitin 1 olma durumuna SET, 0 olma durumuna da RESET denir. İşlemcinin ürettiği bu sonuçlar hakkında programcı bunlara bakarak işlem durumunu analiz eder.
Overflow flag (OF): Biz buna taşma biti de diyebiliriz. İşaretli (negatif)sayı üzerinde meydana gelen taşma durumunu tespit etmek amacıyla kullanılır. Yani işlem sonucunda işaret biti değişmişse bu flag set edilir,yani 1 değerini alır.
Direction flag(DF):Bizim kullanmadığımız bir bayraktır.String işlemlerini yapan komutlar için kullanılır.Yani bir stringi hafızanın bir yerinden diğer bir yerine kopyalarken CPU tarafından kullanılmaktadır. İşlemci bu bayrağa bakarak transferin yönünü belirler.
Interrupt flag (IF):Buna kesme bayrağı da diyebiliriz. CPU’nun çeşitli aygıtlardan gelen kesme isteklerini dikkate alıp almayacağını bildirir. 0 olması durumunda istekler dikkate alınmaz,1 olursa alır.
Trace flag (TF) : Trace biti de diyebileceğimiz bu bayrak CPU nun sadece 1 komut çalıştırma yapması için kullanılır.Hani Debugger ile bir programı açıp programda adım adım ilerliyoruz ya ,işte CPU bunu ,bu bayrağın durumuna göre yapar 1 olursa işletilmeye hazırdır demektir..
Sign flag (SF): Yapılan işlem sonucunda elde edilen sayının en solundaki bit 1 ise bu negatif bir sayıdır demektir ve bu bayrakta 1 değerini döndürür.Eğer ki 0 ise pozitiftir ve bayrak 0 değerini yansıtır.Kısaca bu bayrak sayının negatif veya pozitif olduğunu gösterir.

ADD EAX, EBX

Eğer SF nin değeri 1 ise o zaman EAX deki sayı negatif bir sayı deriz.
Zero flag (ZF) :Bir işlemin toplam sonucu 0 ise bu flag set edilir yani 1, değilse reset yani 0 edilir.Bu bayrağı karıştırmayın arkadaşlar tekrar ediyorum eğer işlem sonunda sonuç 0 ise ,bu bayrak 1 değerini döndürüyor.Mesela;

SUB EAX, EBX

işleminde iki register’ın değerleri eşitse sonuç 0 olacağı için ZF set (1)edilecektir.Aşağıdaki Olly debugger ile aldığım örnek resim olayı kavramanıza yardımcı olacak.

res2we4.jpg


Yukarıdaki resimde JE (jump if equal)komutunu görüyorsunuz burada bir üstündeki OR komutuyla (Daha sonra detaylı şekilde anlatacağım)işlem sonu kontrol ediliyor ve eşitlik var ise JE ile gösterilen adrese atla deniyor.Ancak aşağıdaki resimde gösterdiğim gibi Z bayrağı 0 (sıfır)gösterdiği için atlama gerçekleşmeyecektir.

res3zv9.jpg


Auxilary Carry flag (AF) : Dördüncü bit’ten beşinci bit’e doğru oluşan elde durumunda set edilir. Elde yoksa reset edilir. Özellikle BCD (binary coded decimal) işlemleri için düşünülmüştür.Zaten sizin sık kullanacağınız bir şey değil o nedenle fazla üstünde durmuyorum.

Parity flag (PF) : 16 bitlik bir işlem sonrasında düşük anlamlı byte içerisindeki 1’lerin sayısı çift ise bu bit set edilir 1 olur , tek ise reset edilir o olur. Yani düşük seviyeli bayt bölümündeki 1’lerin sayısı iki ile tam bölünüyorsa bu bayrağa 1 aksi taktirde 0 atanır.

Carry flag (CF) : Bu bayrak da Overflow bayrağına benzer ,ancak aralarında ki önemli fark şu arkadaşlar.Overflow bayrağı işaretli yani negatif sayılar için kullanılır demiştik.Carry (elde)bayrağı da işaretsiz pozitif sayılar için kullanılır.Yine aynı işi yapar yani bir işlem sonunda CPU taşma ile karşılaşırsa carry flag’ın değerini 1 yapar set eder.


ADRESLEMELER :

Bildiğiniz gibi programları oluşturan kodlar ve veriler hafızaya yüklendikten sonra işlemci tarafından satır-satır icra edilirler. Ayrıca CPU tüm giriş-çıkış işlemlerini de hafızaya erişerek yapar. Bazen hafızadan doğrudan bir kod ya da veri alır, işler. Bazen hafızaya bir veri gönderdiğinizde birde bakmışsınız bu bir yazıcıdan belge olarak çıkmış . İşte bilgisayarın donanım ve yazılım olayın da yaptığı bunca çeşitli iş için CPU hafızaya değişik yollardan erişme ihtiyacı duyar. Sizlerde programlarınızı yazarken CPU’nun hafızaya nasıl erişeceğini yazdığınız kodlarla belirtmek zorundasınız. Assembly dilinin bir basamağı olan adresleme modları da bu konuları kapsıyor ve bence iyi bilinmesi gereken bir konu.

Başlıca adreslemeler:

Register (Kaydedici) adreslemesi : Adından anlaşılacağı gibi kaydediciden kaydediciye yapılan işlemlerde bu adresleme modları kullanılır. En hızlı adresleme modu’dur, çünkü işlem hafızada (Bellekte) değil işlemcinin içinde gerçekleşir

mov eax, ebx ; EBX teki değeri EAX’e kopyalar
mov dl, al ; AL teki değeri DL’ye kopyalar (Açılımları yukarda söylemiştik)
mov esi, edx ; EDX teki değeri ESI’ya kopyalar

Kaydedici adreslemede en çok dikkat etmeniz gereken husus hedef ve kaynağın boyutlarıdır. Örneğin 16 bitlik bir kaydediciden 8 bitlik bir kaydediciye taşıma yapılamaz!

mov cx, al ; Yanlış kullanım, AL(8 bit) ile CX(16 bit) eşit boyutta değil.

Hafıza bölgesi adreslemesi : Bu adresleme ile register hafızanın herhangi bir bölgesi işaretlenir. Bunun için MOV komutu yerine LEA (ilerde bahsedeceğim)komutunu kullanabiliriz. MOV komutu registere verilen değeri yükler yada adresler. LEA komutu da aynı işi yapar. Ancak MOV komutundan önemli bir farkı vardır. Verdiğiniz yerdeki değeri değil adresi yükleme yapar. Örneğin:

debug ’Yazi1’,01

lea eax, debug şeklinde verilince EAX registere ’Yazi’ değişkeninin değeri değil bulunduğu yerin adresi yüklenir. Böylece biz bu verinin başından itibaren istediğimiz gibi çalışma yapabiliriz.

Dolaysız adresleme :Bu adresleme registerler arasındaki değerlerin hafıza adresi olarak kullanılması ile oluşan adreslemedir. Buna göre elimizde hiçbir değer yok sadece registerler vardır.

mov dword ptr [esi] ,eax =EAX deki değeri-ESI ile işaretlenen 32 bit hafıza bölgesine yaz

mov byte ptr [eax],bl = Aynı şekilde fakat burada ki değer 8 bit

mov dword ptr [esi],ebx =İlk örnek ile aynı

Burada şu ana kadar bahsetmediğim birkaç kelime var onları anlatmak istiyorum arkadaşlar.Örneğin byte ptr ve [ ] parentez şimdi bunları kısaca açıklayacağım.

byte ptr : Açılımı arkadaşlar (byte pointer) demektir.Eğer yükleyeceğiniz değer 1 byte (8 Bit) cinsinden bir değer ise bunu işlemciye bildirmek zorundasınız ,aksi takdirde hata verir.
word ptr : Bu da arkadaşlar (word pointer) anlamındadır.Ve 16 bittir.Yükleyeceğiniz değer16 bitlik ise yine CPU ya bildirmek zorundasınız…

dword ptr : Bunun açılımı da arkadaşlar (double word pointer) demektir ,yani 16 bitlik 2 sayı anlamındadır.Doğal olarak da 32 bitlik (4 bayt) lık bir değeri temsil eder.

[ ] Parentez : Bu ise arkadaşlar kullanıldığı yerin bir hafıza (bellek) adresi olduğunu gösterir.Bir [ ] köşeli parentez görürseniz o gösterilen yerin hafıza adresi olduğunu bilin..

Dolaylı Adresleme :Bu adreslemede arkadaşlar ileride göreceğimiz PUSH ve POP komutuna benzer olarak istenilen bir hafıza adresine saklama işlemi yapılır. Bu bir register olabileceği gibi bağımsız bir değerde olabilir.Örneğin :

mov dword ptr [deneme],ebx
mov word ptr [00364010] ,4252h

Böylece Registerler ve adreslemeler konusunu da bitirmiş oluyoruz.Ama siz başka makalelerde okuyarak bilginizi sağlamlaştırın derim çünkü değişik kaynaklar her zaman iyidir ama bu kadar anlaşılır olmayabilir .Bundan sonra stack olayına da değinip ,komutlara geçeceğiz.Stack olayı da iyi bilinmeli ve anlaşılmalı arkadaşlar bu nedenle buna da değinmek istiyorum.

STACK ( YIĞIN ) NEDİR :

Gelelim arkadaşlar Stack dediğimiz Yığın konusuna.Bu konuda oldukça basit bir konu yeter ki bu yazdıklarımı dikkatli okuyun.Şimdi program yazan arkadaşlar bilirler ,program yazarken bir değişken kullanırız.Mesela deriz ki; sayi= 24 bu bizim değişkenimizdir.Ve değiştirilmediği sürece hep 24 değerini saklayacak.Ama biz bu değişkene başka değerlerde almak ve 24 değerinin de kaybolmamasını istiyoruz.İşte böyle bir durumda CPU bilgileri geçici olarak saklamak için hem registerleri hem de stack dediğimiz bu bölgeyi geçici yerleşim bölgesi gibi kullanır.Yani bilgilerimizi geçici olarak bu yığına atar ve geri alır.Kısaca Stack, bilgilerin geçici olarak depolandığı bir bölümdür deriz.

Bu yığına giden bilgiler arkadaşlar word uzunluğunda olup en az 2 byte (16 bit) ‘dir.Bu stack alanının bilgisini SP (Stack Pointer) tutar ve buraya gelen verilerin uzunluğuna göre SP kendi değerini azaltır.Buradan değerler geri alındığında ise SP kendi değerini alınan verinin uzunluğu kadar artırır.Bu biraz karmaşık görünebilir ama değil çünkü biraz sonra bunu da bir örnekle anlatacağım .Bu yığına veriler PUSH ve POP komutları ile atılır ve geri alınır.Atarken PUSH komutunu ,alırken de POP komutunu kullanırız.Bunları komutlar bölümünde inceleyeceğiz zaten.

Gelelim şimdi SP in veri alırken değerini azaltması olayına.Arkadaşlar şimdi bir çok bölmelerden oluşan bir kitaplık düşünün (Bu bizim Satck ‘ımız yani yığın bölgemiz).Bu kitaplığımız boş haliyle 100 adet kitap alabiliyor.Biz bu kitaplığa tutar da,5 adet kitap korsak ne olur?Kitaplığımızın %5 ‘i dolmuş olur ,yani boş alanı %95 ‘ e düşmüş yani azalmış oldu değil mi.Kitap alabilme yeri azaldı.İşte Stack ‘ta veri aldıkça boş olan yerleri azalıyor.Şimdi anladınız değil mi.

NOT: Birde unutmadan arkadaşlar bu stack’a atılan veriler ,en sondan başlayarak geri alınır.Yani Son giren veri ilk çıkar.Şöyle diyelim hani biz kitaplığa 5 adet kitap koymuştuk ya,işte bu kitapları geri alırken de ilk önce 5. kitabı sonra 4. sonra 3.-2. ve 1. kitabı alabiliriz.Stack ta da bu böyledir.Tıpkı iç içe açılan For –next döngüsü gibi.En son açılan döngü ilk önce kapatılır. VB ‘ ci olduğum için aklıma bu örnek geldi.

Evet arkadaşlar bu konuyu da bitirdik . Sıradaki bölüm komutlar bölümü.
 
Cevap: [ASM]Assembly Giriş

ASSEMBLY PROGRAMLAMA DİLİ (BÖLÜM -3 )



ASSEMBLY KOMUTLARI :

Evet arkadaşlar geldik komutlar bölümüne ,assembly ‘de komutları kendi aralarında bölümlere ayırmak bence daha iyi olacaktır.Böylece komutların ne işlem yaptıklarını hangi komutların nereler de kullanıldıklarını anlamak daha kolay olur.Ayrıca vereceğim bazı püf noktalar ile de komutlara bakarak ne üzerinde etkili olduklarını hemen kavrayacaksınız.Assembly ‘ de komutları Transfer Komutları, Matematiksel Komutlar, Mantık Komutları, ,Döngü Komutları , Atlama Komutları ve Kaydırma Komutları olarak inceleyeceğiz .Çok gibi görünse de siz bir sefer bu makaleyi okuduğunuz zaman bir çoğunu hemen kavrayacaksınız.Neyse Transfer Komutları ile başlayalım.

Transfer (Veri Taşıma )Komutları :
Bu grup içerisindeki komutlar herhangi bir bilgiyi register-register, bellek-register ve register-bellek bölgeleri arasında transfer etmek için kullanılır.Başlıcaları şu şekildedir.

MOV Komutu: Arkadaşlar önceki bölümlerde birkaç örnek verirken bu komutu kullanmıştım.Şimdi bu komutu yakından inceleyeceğiz anlaşılması kolay bir komut.Adını zannedersem “Move”(taşı) kelimesinden almış.Kullanımı :

Mov Hedef , Kaynak

mov register, register
mov bellek, register
mov register, bellek
mov [adres+register], register
mov register, [adres+register]

vb .şekildedir.Yalnız dikkat edin burada ters bir durum var ,ilk önce hedef sonra ise kaynak adres yazılır mesela Windows da bir veri kopyalarken dikkat ettiyseniz orada önce kaynak ,sonra da hedef bölge yazılır,burada ise tam tersidir.Assembly komutlarının hepsinde önce komut sonra hedef ve araya ( , )virgül koyarak kaynak adres yazılır.Diğer gösterimler ise Mov komutu ile bu bellek ve registerler (kaydedici) arasında ne şekilde veri transferi yapılabileceğini gösterir.Bu komutun bayrak registerleri üzerinde herhangi bir etkisi yoktur.Unutmadan şunu da söyleyeyim taşıma yaptığınız veri ile register aynı değerde olmalıdır.
MOV AX, 1525h
MOV DS, AX

Yukarıda ki örnekte 2 byte lik 1525h (hexdecimal) değer AX (AX burada 16 bit yani 2 bytedir)registere aktarılıyor.Sonra ise AX deki değer DS ‘ye (Data Segment) yazdırılıyor.

LEA (Load Effective Address) Komutu :Bu komut ise Etkin Adresi Yükle anlamındadır.Bu komut Mov komutuna benzetilebilir ancak aralarında etkin bir fark vardır.Mov komutu ile registere bir yerdeki(hafızadan veya registerden) değer yüklersiniz.Oysa LEA komutu ile registere o yerdeki değeri değil,oranın adresini yüklersiniz.Bu şekilde iki yada üç komut ile yapılacak bir işlemi tek bir komut ile yapmış olursunuz.

Kısaca ;LEA komutunun genel kullanım amacı herhangi bir register’a bir bellek adresini yüklemektir. Aşağıdaki kullanım şekli ve örnek açıklayıcı olacaktır.

lea register, adres
lea register, [adres]

dizi db ‘Merhaba’,0

Bu şekilde ki örnekte lea eax, dizi şeklinde yazarsam eax registere ‘Merhaba’ değeri değil de,bulunduğu yerin adresi yüklenir. Böylece biz bu verinin başından itibaren istediğimiz gibi çalışma yapabiliriz. Bu komutun da bayrak registerleri üzerinde herhangi bir etkisi yoktur.

MOVS (Move String)Komutu: Arkadaşlar en güçlü dizi (String)veri transfer komutu olan MOVS hafızanın bir alanından diğer bir alanına veri aktarımı yapar.Yanına aldığı B,W,D takıları ile ayrı bir opkod halini alır ve buna göre bitte işlem yapar. Diğer bir deyişle, bu komut hafızadan- hafızaya veri transferi yapar. Bir MOVS komutu SI(Source index) ile adreslenen hafıza değerini, DI (Destination index) ile adreslenen hafıza alanına aktarır.Yani bir nevi Kaynak-Hedef ilişkisi.

MOVSB = 1 byte işlem için - BYTE(8 bit)
MOVSW = 2 byte işlem için - WORD(16 bit)
MOVSD = 4 byte işlem için - DOUBLEWORD(32 bit)

LODS (Load)komutu: Bu da MOVS komutu gibi yanına aldığı ekin boyutuna göre 8 ile 32 bit arasında işlem gücü kazanır. Temel görevi SI (yada ESI) registerin gösterdiği noktadaki değeri alıp bit değerine göre (AL, AX, EAX) registere (Load)yüklemektir. Ayrıca LODS komutu değeri yükledikten sonra SI registerin değerini kullanılan bit değerine göre arttırarak sonraki veriye göre ayarlamış olur. Bu 8 bit lik veri için 1 byte- 16 bit lik bir veri için 2 byte - ve 32 bit lik bir veri çin 4 byte otomatik olarak toplanacak demektir.

LODSB = 1 byte işlem için (8 bit)
LODSW = 2 byte işlem için (16 bit)
LODSD = 4 byte işlem için (32 bit)

CMPS (Compare)Komutu : CMP komutunun bir değişiği olan bu komut tekil olarak diğerleri gibi yanına aldığı ek ile orantılı olarak bit sayısı kadar işlem(Karşılaştırma) yapar.Yine bu komut SI (veya ESI) ve DI (veya EDI) registerler ile birlikte çalışır.Bu komut tüm karşılaştırma ve test komutları gibi bayrak registeri etkiler. Bu komutu kısaca SI register ile gösterilen bölgeyi DI ile gösterilen bölge ile karşılaştırır diye açıklayabiliriz.. Bu komut ileride göreceğimiz karşılaştırma komutları gibi registerler karşılaştırması yapmaz. Karşılaştırma sonucunu ZF (zero flag) ile alırız. Eğer iki bölgede verdiğimiz bir değerin karşılaştırılması sonucu aynı ise ZF set (1) olur. Eğer yanlış ise ZF reset (0) olur.

XCHG (exchange) Komutu: Exchange komutu iki değerin karşılıklı olarak yer değiştirilmesi için kullanılır.Karşılıklı olarak registerler birbirlerinin değerlerini alırlar. Tabi yine değişim yapılacak değerlerin de aynı boyda olması gerekmektedir.Bu komut da flag register’lar üzerinde herhangi bir değişiklik yapmaz. Kullanımı çok basittir arkadaşlar.

Xchg register,bellek
Xchg bellek,register

Mov ax,1234 ( ax =1234 örnekteki değerler 16 bittir.)
Mov bx,5678 (bx = 5678 )
Xchg ax,bx (ax =5678- bx =1234 değerler yer değişti)

XLAT Komutu :XLAT komutu esas olarak BX (veya EBX) ve AL registeri esas alarak çalışır Genellikle tablo olarak tasarlanan dizilere erişmek için kullanılır. AL kaydedicisine tablonun elemanlarından birini yükler. Bu komutu aşağıdaki örneğe bakarak daha iyi anlayabilirsiniz.

Tablo DB A, B, C, D, E, F

Bu tablonun 4. elemanını AL’ye yüklemek istersek;

MOV AL, 04 ; 04 .eleman sorguluyoruz.İndeks değeri (Diziler 0 dan başlar)

LEA BX, Tablo ; BX’e (taban kaydedici) Tablonun ofset adresi yükleniyor

XLAT ; Tablonun 4. elemanına erişilip E’nin ASCII karakterin hex karşılığı AL’ye yükleniyor(AL=105)

PUSH-PUSHA-PUSHF—POP-POPA-POPF Komutları :

Arkadaşlar Yığın (Stack) konusunu önceki bölümde anlatmıştım. Bu yığın dediğimiz bölge döngülerin döngü sayısını tutmak içinde kullanılır. Ayrıca Bayrak registerlerin (F veya EF) durumu da yığın içinde saklanılabilir.Matematiksel işlemlerde de yığın kullanılır. Bu anlamda yığın çok önemlidir.İşte bu yığına veriyi atmak ve geri almak için de PUSH ve POP komutlarını kullanırız. PUSH ve POP komutları kullanıldığında yığın bölgesinin işaretçisi olan SP (Stack Pointer ) kaydedicisinin durumu da değişir. Tabiî ki bu yığına attığımız veya yığından çektiğimiz değerin boyutuna bağlıdır. 2 byte’lık değer ile işlem yaparak yığına 2 byte lık bir değer atarsak (mesela bu AX kaydedicisinin içeriği olabilir) SP’nin değeri de 2 byte azalır.Anlamadıysanız bir önceki konudan stack konusunu tekrar okuyabilirsiniz…

PUSH komutu herhangi bir bilgiyi belleğin stack adı verilen bölümüne kaydetmek için kullanılır;diye tanımlayabiliriz.PUSH komutu ile stack üzerine atılacak bilgi en az 16-bit uzunluğunda olmalıdır.Komut aşağıdaki gibidir.

PUSH değer

Yukarıda “değer” ile gösterilen kısım daha öncede belirttiğim gibi 16-bit uzunluğunda olmalıdır. Bunun yanı sıra “değer” ile gösterilen kısım sabit bir değer alamaz. Yani PUSH ile stack üzerine yazabileceğimiz değer ya bir register içerisindeki değer yada bir bellek bölgesindeki değer olmalıdır.

mov eax,1234 AX = 1234h değeri atıyorum
push eax AX ‘teki değer şimdi STACK ‘ta ve SP-2 olarak azaldı.

POP komutu ile de stack üzerinden bilgi okuması yaparız. Yani PUSH komutu ile yığına gönderdiğimiz bilgileri POP komutu ile de geri okuruz. Okunacak bilgi 16-bit uzunluğunda olmalıdır.POP komutu ile alınan bilgi stack üzerine yazılan son bilgidir. PUSH ve POP komutları ile bilgi transferi yapılırken yazılan ve okunan bilgilerin sıralaması önemlidir, yine bir önceki konuda açıkladım. Programlar yazılırken stack üzerindeki işlemlerde hesaplama hatası yapmamak için buna dikkat etmek gerekir
.
mov eax,1234 = yukarıdaki örneğimiz
push eax = satck ‘a atıldı
xor eax,eax = eax ‘i boşaltıyorum
pop eax = eax-1234 değeri geri yükledim.

PUSHA-POPA :Bazen bütün register’ların yığında saklanması gerekebilir. Örneğin bir donanım kesmesi oluştuğunda çağrılacak bir kod yazmak istersek kesme çıkışında bütün register’ların ilk konumuna getirilmesi gerekir. Bunun için kesme koduna girişte bütün register’lar stack’ta saklanmalı, ve çıkışta da hepsi geri alınmalıdır.

İşte bu işlemi kolaylaştırmak 80386 sonrası işlemcilere tek komutla bütün registerleri yığına atan ve yine tek komutla hepsini yığından geri alan PUSHA ve POPA komutu eklenmiştir. Kısaca; PUSHA komutu sırasıyla 16 bit sistemde AX, CX, DX, BX, SP, BP, SI, DI kaydedicilerinin değerlerini stack’a atar.POPA da ters sırada geri çeker.
PUSHF : PUSHF komutu da PUSH komutu gibi stack üzerine bilgi aktarır. Yalnız burada ki tek fark, PUSHF komutu ile aktarılacak bilginin herhangi bir register yada bellek bölgesinden değil de flag (bayrak) register’dan alınmasıdır.Yani bayrak registerlerin değeri Stack üzerine atılır.Sonunda ki “F” harfi Flag ( bayrak )anlamında olduğu için karıştırmayacağınıza eminim.Bir de atılacak bilgi doğrudan 16-bit uzunluğundaki flag register içerisindeki değerdir.Komut herhangi bir işlem sırasında bayrak register’ın mevcut değerini korumak için kullanılır.Yine PUSH komutunda olduğu gibi PUSHF komutu da atılan değerin boyutuna göre SP ’nin değerini azaltır. Aşağıdaki gibi tek başına kullanılır…
PUSHF

POPF: POPF komutu ile de arkadaşlar stack üzerine attığımız bayrak değerlerini ,yine 16-bit’lik bayrak register’a geri aktarırız. Ancak geri aldığımız bu 16 bitin hepsi işlemci tarafından dikkate alınmaz.Anlaşılacağı gibi POPF komutu bayrak register ’ın değerlerini tamamen değiştirmektedir. Sonunda ki “F” harfi Flag ( bayrak )anlamındadır.Komut tıpkı PUSHF komutunda olduğu gibi tek başına kullanılır.

Matematiksel (Aritmetik) Komutlar :

Assembly de bütün register arasında standart toplama, çıkarma, çarpma ve bölme işlemleri rahatça yapılabilir arkadaşlar.Ben de burada standart olarak 4 bölüme ayırıp açıkladım. Aritmetiksel komutların icrası sırasında flag registerler değişikliğe uğrar.

a - ADD ve ADC (Toplama)Komutları : ADD komutu toplama işlemini gerçekleştirmek için kullanılır. ADD komutu ile “kaynak” içerisindeki değer “hedef” ile toplanıp tekrar “hedef” register içerisine kaydedilir. “Hedef” ve “kaynak” alanları da register-register, bellek-register, register-bellek gibi çiftlerden birisi olabilir.Örnek olarak;

MOV AX, 5 - ax içerisine 5 değerini yazdık.
ADD AX, 6 - Ax deki değer ile 6 yı toplayıp tekrar Ax ‘e kaydettik.

Yukarıdaki örnekte AX registerimizin değeri 11 olacak ve hexdecimal karşılığı olarak 0Bh yazılacaktı.ADC komutu da tıpkı ADD komutu gibi toplama işlemi için kullanılır arkadaşlar.Aralarındaki tek fark ise ADC komutunda toplama işlemine bir de carry (elde biti) flag’ın değerinin eklenmesidir.Yukarıdaki örnekte işlemin sonucun da eğer carry flag’ın değeri 1 olsa idi, o zaman bizim işlemimizin sonucu da 11 değil 12 olarak çıkacaktı. Gösterimi daha anlaşılır olacaktır.

register = hedef + kaynak + carry flag’ın değeri

b- SUB , SBB ve CMP ( Çıkartma ) Komutları :

SUB (Subtract )komutu çıkarma işlemi için kullanılır. Kullanımı ADD komutunda olduğu gibidir. “Kaynak” içerisindeki değer “hedef” içerisinden çıkartılıp sonuç “hedef” register içerisinde saklanır.Şu şekilde örnek gösterebiliriz.

Mov ax,8
Mov bx,3
Sub ax,bx sonuç ax = 5

SBB Komutu (Subtract with Barrow) ise SUB komutunun Carry’li versiyonudur. Ödünç ile toplama komutu olan SBB, operand ile beraber elde (Carry) bayrağını çıkarmada kullanır.Yani SBB komutu ile SUB arasındaki ilişki, ADD komutu ile ADC arasındaki ilişki ile aynıdır.SUB komutu ile aynı işlem yapılır yalnız burada “hedef” alana atılan değerden carry flag’ın değeri de çıkartılır.
register = hedef – kaynak – carry flag’ın değeri şeklinde gösterebiliriz.

CMP bu komut aslın da karşılaştırma komutu gibi görünse de arkadaşlar CMP komutu kullanım bakımından tamamen SUB komutu gibidir. Ancak işlemin sonucunu herhangi bir kaydediciye yüklemez ,çıkartma işleminden sonra yalnızca bayraklar etkilenir aralarında ki fark sadece budur. CMP ’nin anlamı "compare" yani karşılaştır demektir. Bu komut A, C, O, P, S ve Z bayraklarını etkiler.CMP komutundan sonra sonuca göre genellikle koşullu dallanma komutları ile programın akışı değiştirilir.

Cmp ax, bx

Yukarıdaki örnekte Ax den BX çıkarılıyor AX, BX’e eşit ise işlemin sonucu sıfır olur ve zero flag 1 değerini alır.

INC – DEC (Artırma-Eksiltme ) Komutları :INC ve DEC komutları registerleri, adresleri, yada değerleri azaltmak - arttırmak içindir. Her iki komutta her çalışmasında sadece 1 byte lık azaltma veya arttırma yapmaktadır. Daha fazla adımlarda azaltma-arttırma yapmak için ADD ve SUB komutlarını kullanmalıyız. DEC ve INC komutları oluşturdukları yeni değerlere göre bayrak registeri etkilerler.
Kısaca INC komutu kendisine verilen register yada bellek bölgesi içerisindeki değeri bir arttırır. C
dilindeki “++” komutu ile aynı işi yapmaktadır .Yada VB deki “a = a + 1” ile aynı anlamdadır.

Add ax,1 komutu da aynı işi yapar fakat aşağıda ki örnek daha hızlı çalışır.

inc ax (ax= ++)

DEC komutu da kendisine verilen register yada bellek bölgesi içerisindeki değeri bir azaltır.Yine C dilindeki “--“ komutuna ,yada VB dilindeki “ a = a – 1 ” komutuna karşılık gelmektedir.

Dec ax (ax = -- anlamın da ve oldukça hızlı çalışır)

MUL ve IMUL (Çarpma) Komutları :Çarpma işlevide registerler arasında , adresler arasında, ve kendi arasında uygulanabilir. Çarpma işlemi MUL ve IMUL komutları ile gerçekleşmektedir. İkisini amacı çarpim olduğu halde MUL ve IMUL arasında farklılıklar vardır. MUL işaretsiz çarpma ,IMUL ise işareti dikkate alarak çarpma işlemlerini yapar.Arıca IMUL komutu 2 veya çarpıma olanak vermekte ve kullanım şekli daha geniştir. IMUL komutu 32 bit işlemler için idealdir.

MUL :Aritmetiksel olarak çarpma işlemi iki değer ile gerçekleştirilmesine karşın MUL komutu sadece bir değer alır. MUL komutu ile kullanılan değer gizli olarak ax /al içerisindeki değer ile çarpma işlemine tabi tutulur.Şöyle ki;

mov ax,0045 -ax = 45
mov bx,0011 -bx =11
mul bx -ax * bx = sonuç yine ax registere aktarılır .

Yukarıdaki örnekten anlaşılacağı gibi daima AX (AL ve EAX register) asıl çarpılandır.Eğer bir çarpma işlemi sonucu ax registerin alabileceği en büyük değeri geçiyorsa geçme sayısı DX registere aktarılır. Eğer geçme yoksa DX registerde bir değişme olmaz.
IMUL : IMUL komutu da MUL komutu gibi çarpma işlemi için kullanılır tek fark IMUL komutunun işaretli sayılar üzerindeki işlemler için kullanılan bir komut olmasıdır.Ayrıca IMUL komutu çoklu register ve büyük değerlerle işlem yapmaya olanak vermektedir. Yanlız MUL komutunda olduğu gibi taşma olduğunda DX register aktarılma yapılmaz. IMUL ile üçlü çarpımda mümkündür.

mov ax, 04h
mov bx,05h
imul ax,bx,8h ; [AX*BX] * 8 = 160

Yukarıda sadece küçük sayılarla örnek verdim anlaşılması için yoksa bu komutla daha büyük sayılar çarpılabilir.32 bit işlemcilerde bu komut kullanılır.

DIV ve IDIV (Bölme) Komutları : Bölme komutuda DIV ve IDIV olmak üzere kapsamlı olarak iki tanedir. DIV komut da MUL komutundan olduğu gibi sadece bir değer ile işleme girer ve gizli olarak AX register’ını kullanır. Yani işlem sonundaki bölüm değeri AX ve kalan değeri de DX içerisine atılır.DIV division yani bölme kelimesinin kısaltmasıdır, dikkat edilmesi gereken bir diğer husus da sıfır ile bölme durumudur. Diğer işlemlerde olduğu gibi bölme işleminde de matematik kuralları geçerlidir ve matematikte "sıfıra bölme" anlamsızdır. CPU’ da sıfıra bölüm için özel bir kesme(interrupt) ayırmıştır ve böyle bir durum da işlemi durdurur.

Mov ax,10
Mov bx,3
DİV bx

bx deki 3 değeri ax deki 10 değerine bölünüyor ve ax de 3 değeri ,kalan 1 ise DX registerde saklanıyor.
IDIV komutu ise aynı IMUL komutunda olduğu gibi daha yüksek işlemler için idealdir.Ayrıca IDIV komutu işaretli sayılar üzerinde işlem yapmak için kullanılır.Bu komutu fazla kullanmayacağınızdan bu kadar yeterlidir diye düşünüyorum.

Böylece Matematiksel komutları da bitirmiş olduk sıra son bölümde.
 
Cevap: [ASM]Assembly Giriş

ASSEMBLY PROGRAMLAMA DİLİ (BÖLÜM -4 )


ASSEMBLY KOMUTLARI :

Mantık Komutları: Arkadaşlar Mantıksal işlemlerde VE, VEYA, DEĞİL, VEYA DEĞİL gibi mantık karşılaştırmaları vardır. Bunlar assembly de AND, OR, XOR, NOT komutlarıyla işlevlerini gerçekleştirirler. Buradaki amaç en iyi seçenekleri bulmak ve istenildiği şekilde gruplama yapabilmektir. Mantıksal yani diğer adıyla Lojik işlemler bit’lerin temizlenmesini (0’lanmasını), 1’lenmesini veya tersinin alınmasını sağlar. Bütün lojik işlemler bayrak bit’lerini etkiler.Şimdi bu komutları görelim.
AND komutu : AND komutu işlem sırasında “hedef” ve “kaynak” bölgesindeki değerleri mantıksal VE işlemine tabi tutar ve işlemin sonuncunu “hedef” alana kaydeder. Yapı olarak AND (VE) mantığı 1 ve 0’lar ile ifade edilirse aşağıda ki şekilde açıklayabiliriz;
1 ve 1 = 1
1 ve 0 = 0
0 ve 1 = 0
0 ve 0 = 0
sonuçlarını üretir.Yukarıda da görüldüğü gibi arkadaşlar her iki değerde 1 ise sonuç 1 oluyor.Aksi durumlarda sonuç hep 0 olur. Bu komutu assembly programcıları genelde maskeleme işlerinde kullanırlar Aşağıdaki örnek açıklayıcı olacak;

Mov ah,09h - ah ye 9 değerini yükledik
Mov al,05h - al ye 5 değerini yükledik
And ah,al - And işlemine tabii tutup sonucu AH de saklıyoruz.
Yukarıda ki işlem şu şekilde işleyecektir.

Ah = 00001001
Al = 00000101
And =---------------
00000001 = sonuç 1 olacak ve Ah ye yazılacaktır.Bu şekilde maskeleme yaparak 4 bite dokunmadan diğer bitleri sıfırlamakta denilebilir.

TEST Komutu : TEST komutu tamamen AND komutu gibi çalışır. Tek fark elde edilen sonucun hedef alana aktarılmaması onun yerine değişen flag bitlerine göre programın akışının kontrol edilmesidir.
OR Komutu : Bu komut da arkadaşlar mantıksal VEYA işlemine tabii tutar.Yukarıda ki AND işlemi gibi bitlerle işleme sokulur.OR işleminde her iki değerden birinin 1 olması durumunda sonuç yine 1 olur.Sadece her iki değerde 0 olursa sonuç 0 olur.Aşağıdaki tablo açıklar nitelikte.

1 veya 1 = 1
1 veya 0 = 1
0 veya 1 = 1
0 veya 0 = 0

XOR Komutu : XOR komutunu arkadaşlar şu şekilde açıklayabiliriz, iki operand aynı ise 0, farklıysa 1 değerini veren bir işlemdir.Yada "aynılarda 0 farklılarda 1" sonucunu veren mantıksal ifadedir diyebiliriz. Özellikle şifreleme işlemlerinde tercih edilir ayrıca program içerisinde bir registerde ki değerleri sıfırlamak içinde kullanılır.Örneğin XOR EAX,EAX gibi bir kullanımda EAX içerisindeki değer sıfır olur ,bu kullanım MOV EAX,0 komutuyla aynı işi yapmasına rağmen XOR komutu daha hızlı ve seri çalışır.. Bir sayıyı kendisiyle XOR işlemine sokarsak 0 elde ederiz..
1 -- 1 = 0
1 -- 0 = 1
0 -- 1 = 1
0 -- 0 = 0

NOT Komutu : NOT komutu "değil" anlamına gelir. Bunu bitlerin değili anlamında düşünürsek 1 ise 0 ; 0 ise 1 demek oluyor. Yani bitleri tam tersine çevirmiş oluyoruz.. NOT komutu diğer mantıksal komutlardan ayrı olarak flag register üzerine etki etmeyen tek komuttur. Kullanım şekli ile de diğer komutlardan farklılık gösterir. Direk “hedef” alan içerisindeki değerin bitleri ters çevrilip yine aynı alana yazılır.

1 Değil = 0
0 Değil = 1

Döngü Komutları : Evet arkadaşlar her programlama dilinin vazgeçilmezi olan döngü komutları da assembly ‘de aynı yere sahiptir.Döngü komutları verilen herhangi bir rutini koşul sağlanıncaya çalıştırır.Diğer dillerde ki For-next veya while-wend komutları gibi. Döngü komutları genelde şunlardır: LOOP, LOOPE, LOOPNE, LOOPZ, LOOPNZ. Bunlar CX (Count Register) yada ECX registerin durumuna göre işlem yapar..Döngü komutları LOOP ile başlar ve yanına aldığı ayrı bir opkod oluşur. Aldığı ek işlemi yapma ve devam etme şartıdır. Bu komutlar daima CX (veya ECX) register ile birlikte çalışır. Şartı ve döngü uzunluğunu bu sayaç register oluşturur. Daha önce gördüğümüz bayraklar burada da etkindir. Karşılaştırma ve şartın yerine getirilmesi kontrolu Z (sıfır bayrak = zero flag) ile kontrol edilir. Döngüyü kaplayan alanın bir sınırı vardır. Bunun nedeni ise döngü noktasını belirten değerin 8 bitlik bir sayı olması. Bu kodun +127 byte yukarı ve -128 byte aşağıya kadar ulaşması demektir.

LOOP Komutu : LOOP komutu arkadaşlar o andaki CX (Count Register) yada ECX sayaç registerinin değeri 0 oluncaya kadar döngüyü işletir. Şartı sayaç registerin 0 olmasıdır. Yani her döngüde CX içerisindeki değer bir azaltılır ve CX’in değeri sıfır oluncaya kadar işlem devam eder.


XOR AX, AX AX degerini sıfırladık
MOV CX,0005 CX 5 degerini atadık
INC AX AX 1 eksilt
LOOP Tekrar INC komutuna dönecek

LOOPE ve LOOPNE Döngüleri : Eşit olması yada olmaması gibi bir durum kontrol eder. Burada yapılan işlem diğerleri gibidir ve pek bir fark yoktur.Loop kelimesinin sonundaki ”E” eşit (Equal) ve “NE” kelimeside (Not Equal) yani eşit değilse anlamındadır.Böyle bir döngü ile karşılatıgınız zaman ne anlamı oldugunu hemen anlarsınız.Burda CX deki değer verilen şarta eşit ise veya değil ise döngü ona göre çalıştırılır.

LOOPZ ve LOOPNZ Döngüleri : Bu döngüler bir işlemin sonucu 0 ise zero flag bitinin (sıfır bayrak biti) olması durumuna göre çalışır. Genelde bu döngü komutları daha çok kullanılır ve ikiside sayaçlı bir döngü işlemi için yeterlidir. LOOPZ komutu (Sonundaki “Z” opkodu Zero yani sıfır anlamında) CX veya ECX registerin o değerine ulaşıp ulaşmadığını kontrol eder. Bir bakıma yukarıda bahsettiğim LOOP komutu gibidir ve tek farkı bayrak kontrolu olmasıdır. LOOPNZ ise 0 değilse durumunu kontrol eder. Yani sayaç registerin değeri 0 değilse devam eder.

ATLAMA KOMUTLARI

Namı diğer Dallanma komutları, programın normalde yukarıdan aşağı doğru giden akışını herhangi bir koşula bağlı olarak yada koşulsuz olarak başka bir yere yönlendirmek amacı ile kullanılır. Kullanılan bu dallanma komutları yüksek seviyeli dillerdeki “if” veya “goto” komutları gibi düşünülebilir.
Assembly dilinde kullanılan dallanma komutları atlama yaptıkları yere göre FAR veya NEAR özelliği taşır. NEAR özelliği taşıyan komutlar 2-3 bayt yer tutarken FAR özellikli olanlar 5 bayt yer tutmaktadır. Komutlar arasındaki fark, FAR özelliği taşıyanların farklı segment içerisindeki noktalara dallanma için kullanılmasıdır. Gerekli olmamakla beraber dallanmanın türü “FAR PTR” yada “NEAR PTR” ile belirtilebilir.

JMP (Koşulsuz Dallanma) Komutu: JMP komutu belirtilen herhangi bir noktaya koşulsuz olarak dallanma yamak için kullanılır.
jmp hedef şeklinde gösterilebilir.Aşağıda karşılşabileceğiniz atlama komutalarını ve anlamlarını içeren bir tablo veriyorum.Bu tablo çok işinize yarayacak.


Hex Kodu: ASM Kodu: Anlamı:

75 yada 0F85 jne jump if not equal
74 yada 0F84 je jump if equal
EB jmp jump directly to
90 nop no operation
77 yada 0F87 ja jump if above
0F86 jna jump if not above
0F83 jae jump if above or equal
0F82 jnae jump if not above or equal
0F82 yada 72 jb jump if below
0F83 yada 73 jnb jump if not below
0F86 yada 76 jbe jump if below or equal
0F87 jnbe jump if not below or equal
0F8F yada 7F jg jump if greater
0F8E jng jump if not greater
0F8D jge jump if greater or equal
0F8C jnge jump if not greater or equal
0F8C jl jump if less
0F8D jnl jump if not less
0F8E jle jump if less or equal
0F8F jnle jump if not less or equal

Şimdide isterseniz bu atlama komutlarının ne işe yaradığını kısaca anlatayım arkadaşlar..

JZ/JE Komutları : JZ/JE (Jump if Zero/Jump if Equal) komutları herhangi bir işlem sonrasında zero flag’ın değerine göre programın akışını düzenler. Komutun icrası sırasında zero flag içerisindeki bit değeri 1 ise program JZ komutu ile gösterilen yere atlar aksi taktirde işlemci JZ komut yokmuş gibi programın akışına devam eder.

JNZ/JNE Komutları : JNZ/JNE (Jump if Not Zero/Jump if Not Equal) komutları JZ ve JE komutlarının zıttı olarak kullanılır. Herhangi bir işlem sonrasında zero flag içerisindeki değer sıfır değil ise program komutun gösterdiği yere dallanarak akışına devam eder.

JB/JC/JNAE Komutları : JB/JC/JNAE (Jump if Below/Jump if Carry/Jump if Not Above or Equal) komutları carry flag’ın değerine göre dallanma gerçekleştirirler. Herhangi bir işlem sonrasında carry flag
içerisinde 1 değeri varsa programın akışı JB komutu ile gösterilen yere gider. Aksi taktirde JB komutu dikkate alınmadan programın normal akışına devam edilir.

JBE/JNA Komutları : JBE/JNA (Jump if Below or Equal/Jump if Not Above) komutlarının icrası sırasında carry ve zero flag’ları kontrol edilir. Bir işlem sonrasında iki flag’dan birinin 1 olması durumunda JBE komutu ile gösterilen noktaya dallanma yapılır.

JL/JNGE Komutları :JL/JNGE (Jump if Less than/Jump if Not Greater or Equal) komutlarının gerçekleşmesi için gerekli koşul carry ve overflow flag bitlerinin birbirinden farklı değerler taşımasıdır. İki bitin farklı değerler içermesi durumunda programın akışı JL komutu ile gösterilen noktaya yönlendirilir.

JS ve JNS Komutları : JS (Jump if Sign) ve JNS (Jump if No Sign) komutlarının icrası sırasında sign flag kontrol edilir. Sign flag içerisindeki değerin 1 olması JS için, sıfır olması JNS için gerekli koşuldur. Gerekli koşulun sağlanması durumunda program JS veya JNS komutu ile gösterilen noktadan akışına devam edecektir.

JO ve JNO Komutları : JO (Jump if Overflow) ve JNO (Jump if No Overflow) komutlarının icrası sırasında overflow flag içerisindeki değere bakılır. Overflow flag içerisinde 1 JO komutu için ve sıfır olması JNO komutu için gerekli koşuldur.

KAYDIRMA ve DÖNDÜRME KOMUTLARI

Bit çevirme ve kaydırma komutları pek çok alanda kullanılır. Grafiksel işlemlerde, çevrim işlemlerinde, sayaçlarda,... Bit kaydırma kendi arasında kaydırma komutları ve çevirme komutları komutları olarak ikiye ayrılır. Kaydırma komutlarıda aritmatik ve logical olarak ikiye ayrılırlar. Bunların arasında işlevsel bir farklılık vardır. Kaydırma komutları biti sonuç 0 oluncaya kadar sağa yada sola doğru kaydırır. Kaydırılan bit yokolur ve tersine işlem yapılsa bile geriye dönemez. Çevirme komutları ise bitleri çevirerek dönüşüm yapar ve bit sayısına bağlı olarak tekrar eski değerine ulaşır. Çevirme komutlarında hiçbir bitin değeri kaybolmaz. Daima çevrimiçi olarak kalır. İki komut grubunda da sağa ve sola kaydırma mevcuttur ve ingilizcedeki left, right kelimelerinin başharfleri ile belirtilirler. Bu komutlar yardımcı register ile kullanılarak blok kaydırma veya çevirme işlemlerine tabi tutulabilirler. Yardımcı register değişmez olarak CL registerdir ve burada bir sayaç görevini üstlenir. Registerdeki sayının bitini şu kadar kaydır diye komut verebiliriz. Özellikle aritmatiksel kaydırma komutları register-register kullanılımı ile kaydırmak işlevine sahiptirler. Burada kaydırma sayısı registeri 0-31 sayıları olmak zorunda çünkü şu anda bu komutlar en fazla 32 bitlik registerleri kullanabiliyor.
Mantıksal kaydırma ve çevirme komutları bildiğimiz matematiksel bölme ve çarpma işlemlerinin aynısı yaparlar. Sağa doğru yapılırsa çarpma, sola doğru yapılırsa bölme işleminin aynısını yapmış olurlar.

Mantıksal kaydırma komutları : Örnek olarak elimizde eax registerde 00111000 şeklinde bir sayımız var. Bu sayıyı 1 bitlik kaydırma işlemine tabi tutuyoruz:

MOV EAX ,00111000
SHL EAX,1
Eax=01110000

Burada shl eax,1 komutu ile eax registerdeki bitleri sola doğru (shl= sola , shr = sağa) kaydırdık. Örnektede görüldüğü gibi ilk bit 0 oldu ve ilk set olan bit sola doğru kaydı. Sonuçta sayının değeri iki katına çıkmış oldu. Çünkü basamak atladı.Eğer biz bu işlemi 5 kere daha yaparsak bütün bitler sola doğru kayacağı ve yerlerin resetleyeceği için sonuç 0 olacaktır. Yani sayı döngü içinde mutlaka 0 değerine ulaşacaktır. Buradaki 0 değeri olarak bahsettiğim bitlerin tamamının sıfırlanması ve sayıyın değerini tamamen kaybetmesi oluyor.

shl eax,1 ; 01110000 <-
shl eax,1 ; 11100000 <-
shl eax,1 ; 11000000 <-
shl eax,1 ; 10000000 <-
shl eax,1 ; 00000000 <-

Eğer sayıya shr işlemine (sağa kaydırma) tabi tutarsak:

shr eax,1 ; 01110000 ->
shr eax,1 ; 00111000 ->
shr eax,1 ; 00011100 ->
shr eax,1 ; 00001110 ->
shr eax,1 ; 00000111 ->
shr eax,1 ; 00000011 ->
shr eax,1 ; 00000001 ->
shr eax,1 ; 00000000 ->

Mantıksal Döndürme komutları:Mantıksal döndürmek komutları aynı kaydırma komutları gibi bitleri sağa yada sola kaydırır yalnız bitlerin değeri kaybolmaz her kayan bitin yerine bir önceki bit gelir. Son bit ilk bir ile yer değiştirir veya ilk bir son bit ile yer değiştirir. Eğer döndürülecek registerin değeri 0 değilse ve değerini yokedecek başka bir işlem yapılmıyorsa değeri asla 0 olmaz. Çevrimi bir daire gibi düşünebiliriz. Aynı dünyanın güneş etrafında dönüşü gibi belli bir süre sonra bitler tekrar aynı yerlerine gelecektir. Yine kaydırma komutarı gibi tek tek yada yardımcı register vasıtasıyla birden fazla kombine çevrim mümkündür.
Ayrıca RCR ve RCL çevirme komutlarıda CL register ile kombine kullanılır. İşlevleri aynıdır ancak C bayrağı ile birlikte kullanılır. Bu sayede döndürme işlemini bayrak bazında kontrol altına alabiliriz. Örneğin döndürülen sayının 0 olması durumda.

mov ax,0111000
mov cl,5
rcl ax,cl

Evet arkadaşlar böylece Assembly makalesini de bitirmiş oluyoruz.Dediğim gibi Assembly insana uzak ama makine ya yakın bir dil.Ama öğrenilmeyecek bir dilde değil.Umarım faydalı olabilmişimdir.Sevgilerimle….


DN: Konu Alıntıdır.
 
Son düzenleme:
Cevap: [ASM]Assembly Giriş



Senin aklında sorunmu var ? Bu programlama dili için açacağım konunun yeri olmadığını buraya açtığımı belirttim. Ayrıca güzelimde ney sen &quot;top&quot; musun ? Hönk

CW akar..


konu alıntıdır ve onuda yaz lütfen.
 
Cevap: [ASM]Assembly Giriş

Hatırlattığın için teşekkürler. Düzenlemeden dolayı unutmuşum.
 
Cevap: [ASM]Assembly Giriş

bişey deil ASM ile ilgili başka makalelerde olucak.
 
Cevap: [ASM]Assembly Giriş

:D top sizsiniz lean düzgün konusun ipneler keşke küfür etseydim daha iyi olurdu demi
 
Cevap: [ASM]Assembly Giriş

Eğer ilgi çoğalırsa başka türlü anlatımlarda paylaşacağım.
 
Son düzenleme:
Cevap: [ASM]Assembly Giriş

Çok yararlı buldum konuyu teşekkür ediyorum.Moderatörler konunun yerinin burası olmadığına kanaat getirirlerse zaten taşırlar bize "burası yeri değil be güzelim" gibisinden şevk kırıcı sözler söylemek düşmez.Paylaşımcıya biraz destek olun.
 
Geri
Üst Alt