< Asembler Dili (Assembly Language) 3 - Computer & Technology & Science - Blogcu





14/4/2006

Asembler Dili (Assembly Language) 3

 

ATLAMALAR ve ATLAMA komutlari

Atlama komutlari döngü komutlarindan farkli olarak istedigimiz sartlara göre dallanmayi saglar. Atlama komutlari karsilastirma komutlari ile veya karsilastirma komutlari olmadan da kullanilabilir. Ancak özel durum ve hassas degerler için karsilastima komutlari mutlaka gereklidir. Bunun için öncelikle karsilastirma komutlarini ögrenmemiz gerekir.

Karsilastirma komutlari bayrak registerin bitlerine göre hareket eden, bayrak registerin ilgili bitlerinin set veya reset yaparak sartlari olusturan komutlardir. Daha önce CMPS komutundan bahsetmistim. Bu komut ESI ve EDI ile karsilatirma yaptigi gibi ECX ile uzun ölçekli karsilatirmalarda yapar. Karsilastirma komutlari genel olarak CMP komutu altinda toplanmistir. CMP komutu aynen registerin adreslemelerinde anlattigim gibi çok genis bir adresleme sahasina sahiptir.

cmp reg1,reg
cmp reg1,deger
cmp [addr],reg1
cmp [addr]deger

gibi karsilatirma olanaklari mevcuttur. Kombine kullanimlarda bu etki daha da arttirilir. Örnegin bir hafiza bölgesinde analiz yapmamamiz gerekiyorsa ve sadece sayilari bulmak istiyorsak <0 ve >9 olarak mantik formülü kurabiliriz. Bunuda "eger veri 0 sayisi ASCII (0 ASCII sembolu 30h)  sembolünden küçükse ve 9 sayisi ASCII  (9 ASCII sebolu 39h) sembolünden büyükse bu bir sayi degildir diyebiliriz. Bunu Assembler olarak ifade etmek istersek :

cmp byte ptr [bölge],30h
ve
cmp byte ptr [bölge],39h
ise dogru degilse yanlis
seklinde sembolik olarak ifade ederiz. Burada geriye kalan sadece karsilastirma kosuluna göre dallanma yapan atlama komutlaridir. Tam halini yazacak olursak:

 

cmp byte ptr [bölge],30h
jl düsük
cmp byte ptr [bölge],39h
ja büyük

Yani ASCII kodlarini bildigimiz 0 ve 9 sayilarinin sinirlari içindemi seklinde bir sinama yapmis oluyoruz. CMP komutu gibi bit karsilastirmasi yapan TEST komutuda vardir. TEST komutunun özünde bit karsilatirmasi vardir ve özellikle lojik islemlerde çok kullanilir.

TEST Komutu

TEST komutunun CMP komutundan en büyük farki karsilastirilan degerlere mantiksal AND isleminin uygulanmasidir. AND komutunun  islevini daha sonra ayrintili olarak görecegiz ancak kisaca bahsetmem gerekirse AND islevi karsilastirma sonucunda iki bitte eger 1 ise sonuç biti 1 (set olur) diger durumlarda 0 (reset) olur. Tabi sonuç tam tersi oldugu için bu karsilastirma sonuçlari yukarida bahsettigim sartli karsilastirma komutlarinin sonuçlarindan farkli (tersi) olur. Ayni sekilde atlama komutlarinda oldugu gibi standart bayrak (flag register) bitlerini kullanir.

AND islevi ( her sütunu yukaridan asagiya olarak inceleyeyin )

Kaynak bit

1

0

1

0

Karsilastirilan bit

1

1

0

0

Islem sonucu

1

0

0

0

Sartli atlamalar

Karsilastima komutlarini kisaca anlattiktan sonra karsilastirma sonuçlarini nasil yönlendirecegimizide ögrenmemizin zamani geldi. Yaptigimiz her karsilastirma sonucu ne olursa olsun bayrak registeri etkiler. Daha önce iç-içe döngülerde anlattigim gibi karsilastirma durumlarida yigin bölgesine atilarak o andaki durum korunabilir. Bunun için PUSHF, PUSHFD ve POPF,POPFD olarak özel komutlar olusturulmustur. Bu komutlar o andaki bayrak registerin degerini yigin (ESP ile gösterilen bölgeye) bölgesine atabilir. Sonra tekrardan alip o andaki durum tekrar ortaya çikarilabilir. Bu durum ortaya baska bir özelligi çikarmistir. Normalde bayrak registeri sadece karsilastirmalar ile degistirmiyoruz, yigin üzerinden alinan bayrak register degerini lojik komutlar ile degistirerek tekrar bayrak registere aktarir ve istedigimiz ortami olusturabiliriz. Bunlari yapmaya gerek kalmadanda bazi özel komutlar ile istedigimiz ortami olusturabiliriz. Örnegin CLC ve STC komutlari bizim bayrak registerin CARRY bitini degistirmemizi saglar. Programlar içinde Carry biti anahtar gibi kullanilabilir.

Iste bütün bu islemlerin yapilma amaci programin içinde istedigimiz sartlari olusturmak ve bu olusturdugumuz bu sartlara göre programa yön vermektir. Cümle olarak ifade edersek " a sayisi b sayisindan büyükse baska sayi seç degilse a sayisini aktar" seklindeki programa uygulayacagimiz algoritmalari bunlar sayesinde yapariz.

Birde karsilatirma komutu kullanmadan yapabilecegimiz dallanmalar var. Her ne sekilde olursa olsun bir programin akisinda eger registerlerden birisi sifir yada sifir oluyorsa mutlaka Z (Zero flag) set (yani 1) olur. Öyleyse CMP yada TEST komutu kullanmadan da atlama yapabiliriz.

Atlama komutlariyla ilgili küçük bir tüyo vermek gerekirse, sartli atlama komutlarinin yanina gelen "e" harfi ile kendi sarti ile birlikte esit olmasi durumunuda kontrol eder. Ayrica sartli atlama komutlari +127 -128 aralikla atlama yaptigi gibi opkodu degiserek (bizim birsey yapmamiza gerek olmadan derleyici otomatik olarak yapar) 16 ve 32 bit atlamada mevcuttur. Asagidaki listede belirttigim gibi JMP komut haricindeki diger tüm atlama komutlari eger sartli yerine gelmiyorsa kendinden sonraki opkod ile yoluna devam eder.

 

 

 

 

 

Simdi sartli atlama komutlarini inceleyelim.:

JMP

Bu komut sartsiz atlayan tek komuttur. Hiçbir sarta bagli olmadan atlar ve kendisinden sonraya devam etmez.

JA-JAE

Büyükse atlama komutudur.  JAE ise büyük ve esit ise dallanmadir.

JB-JBE

Küçük ise atlama komutudur. JBE ise küçük ve esit ise dallanmadir.

JC   

C (Carry) biti 0 ise atlama yapar.

JCXZ - JECXZ 

Eger ECX (yada CX) register 0 ise dallanma yapar.

JE  

Eger esit ise. Bu istedigimiz bir degeri sartlandirmamiza yarar.

JG -JGE   

Eger büyükse, JA dan farki Z ve SO bayrak bitlerini kullanmasi.

JL-JLE  

Eger küçükse, JLE ise hem küçük hemde esitse dallanma yapar.

JNA-JNAE

Eger yukarisindaysa, tasma varsa, JA gibi ancak kullandigi bitler farklidir.

JNB-JNBE

Eger asagidaysa, JB gibi ancak kullandigi flag farkli.

JZ  

Eger 0 ise atlama yapar.

JNZ

Eger 0 degilse atlama yapar.

JS

Eger S (Sign = isaret) biti set (yani 1)  ise.

JNS      

Eger S (Sign = isaret) biti reset (yani 0)  ise.

JO  

Eger tasma (Overflow) biti set ise.

JNO 

Eger tasma (Overflow) biti reset ise.

JP  

Eger esitlik (Parity) biti set ise.

JNP   

Eger esitlik (Parity) biti reset ise.


Ayni sekilde 16 ve 32 bitlik atlama komutlarida vardir. Isimleri aynidir yalniz opkodlari farklidir. Derleyiciler son asamadan bunu uzakliklari hesaplayarak kendileri tayin ederler. Ancak kendimiz hex olarak opkod yazmak istersek ve 8 bitlik bir dallanma yada tam tersini kullanirsak o komutun alanina ve sinirlarina göre hareket eder. Atlama komutlari bu kadarla sinirli degildir. Ben burada en çok kullanilan ve kullanim alani en genis olanlari verdim. Diger atlama komutlari özel amaçlar için kullanilabilir.

Atlama komutlarinin temelinde karsilastirma ve bu karsilastirma sonucunda sartlari olusturuyorsa atlayacagin yer vardir. Atlayacagin yere kisaca LABEL yada ETIKET diyoruz. Editör ile bir assembler programi yazarken eger bir atlama komutu kullaniyorsak mutlaka atlayacagi yeride belirtmemiz gerekiyor. Aksi halde hata mesaji alir ve programi çalistiramayiz. Bütün Assembler dillerinde etiket daima harf ile baslar ve sonunda mutlaka" iki nokta üst-üste" olur. Örnegin:

buyukse:
altama12:
L20001:

gibi. Burada küçük bir kural daha vardir, etiket isimlerinde büyük- küçük harf hassasiyeti vardir. Hepsi büyük harf veya hepsi küçük harf olarak kullanilacak diye bir kural yok ancak atlama komutunun sembolu ile etiket ayni harf sekline sahip olmadir. Etiketler derleyiciler için semboliktir ve derleme sirasinda neyin nereye gidecegini - atlayacagini sembolize eder.

Örnekler:

1) Burada yazi içinden 'h' harfi araniyor ve bulunca "buldum" isimli etikete gidiyor. Burada sayi verilmedigi için arama islemi 'h' harfini buluncaya kadar devam ediyor.

veri    db 'Assembler hizlidir',0
....

        lea esi, veri   
ara1:
        lodsb
        cmp al,'h'
        je buldum
        jne ara1
        buldum:
        .....


2)

yazi        db 'CW dostlarina selamlar!',0
key         db 0
....

          lea esi, yazi
          mov ecx,5
          xor eax,eax
          xor ebx,ebx
topla:
            lodsd
            add ebx,eax
            loopnz topla
            cmp ebx,12345678
            jz crc_ok
            mov byte ptr [key],0
             ret
crc_ok:
            mov byte ptr [key],1
            ret

Burada da verilen yazi toplaniyor ve istedigimiz sonucun çikip - çikmadigina bakiliyor. Eger sonuç dogru ise "key" olarak belirtigimiz hafiza bölgesini 1 yapiyor degilse yoluna devam edip 0 yapiyor. Basit bir algoritma. Burada "key" bölgesi illaki 1 veya 0 yapilmak zorunda degil. Kullanici programin aksina göre istedigi gibi degerler kullanabilir.

 

 

CMPXCHG Komutu

CMPXCHG komut iki komutun birlesik tek bir komut olarak tasarlanmasi sonucu ortaya çikmistir. Daha önce gördügümüz CMP ve XCHG komutlarinin islevini kombine bir sekilde yapar. Bu komut A registerler (AL, AX, EAX) için tasarlanmistir. CMPXCHG komut ile EAX register ile baska bir deger yada register karsilastirilir ve sonuç ayni ise karsilastirilan deger ile A register degeri yerdegistirir. Optimize kullanimlar için gerçekten ideal bir komuttur.

CMPXCHG8B komutu

Ayni CMPXCHG komutu gibidir ancak 64 bitlik bir islem kapasitesi vardir. Bu komut CMPXCHG komutu gibi EAX registerle beraber EDX registeride asil olarak kullanir. ECX :EBX register degerler EDX:EAX ayni ise ikisi yer degistirir. Daha büyük islemler için idealdir.

JMP KOMUTU

JMP komutu bagimsiz bir atlama komutudur. Bu komut ile gösterdigimiz yere atlanir ve program buradan itibaren devam eder. JMP komutu sartli döngüler içinde geri dönüsüm atlamasi içinde kullanilir. Ancak mutlaka döngüyü kesecek bir kontrolde eklemek gerekli yoksa döngü sonsuz olacak dolayisiyla islem yerine getirilemeyecektir. 

Örnek döngü:

        lea esi,yazilar
dis1:
lodsb
cmp al,'A'
jz buldum
jmp short dis1
buldum:
......

Burada görüldügü gibi yazilar bölgesinden 'A' harfini ariyoruz. Bu aramanin bir limiti yok. Buluncaya kadar ESI registerin degeri LODSB ile yükseltilip AL degeri alinacak. Eger bulursa "buldum" olarak belirttigimiz yere atlayacak ve döngüden çikilmis olacak. Eger alinan deger 'A' degilse JMP SHORT DIS1 ile direkt atlama yapilarak döngü devam edecek. Burada SHORT kisa mesafelerdeki atlamalar için kullanilan bir ek. JMP komutu uzun ve kisa atlama olarak ikiye ayriliyor. Eger hiçbir sey belirtmezsek derleyici uzun olarak algilar ve bu opkod 6 byte uzunlugundadir. Kisa olan ise sadece 3 byte uzunlugundadir ve bu sayede programda 3 bytelik bir alan optimizesi yapmis oluyoruz. SHORT ekini kullanmak zorunlu degildir.

CALL  ve RET komutu

CALL komutu sartli atlama komutu degildir. Programin akisi içerisinde istenildigi zaman baska bir yere sartsiz atlanarak oradaki kodun çalismasi saglananilir. CALL sartli degildir ancak RET komutu ile kombine çalisir. Bunun en büyük nedeni ise CALL komutunun diger atlama komutlarinda olmayan bir özelligindir. CALL komut çagrildigi yerde islemlerini tamamladiktan sonra RET komutu ile çagrildigi yerin sonrasina devam eder. Böylece program bir akiskan düzen üstüne oturtulmasi ve çagrilan prosedurun (kod blogu) sonuçlarinin alinip kullanilmasi saglanmis olur. CALL ve RET komutlari yigin bölgesiyle çalisir. Zaten geriye dönüs yigin bölgesine atilan CS ve IP register degerleri ile mümkün olur. Bu yigina atma islevi tamamen CPU tarafindan olusturulur ve programci isinin bitip geriye dönmesini istedigi yere RET komutunu koyar. Bu komut o andaki yigin bölgesinden CS ve IP register degerlerini alir ve geriye dönüsümü saglar. Ancak burada dikkat edilecek bir nokta var. Eger çagrilan prosedur içinden yigina atma islemi yapilip tekrar geriye alinmadiysa yigin bölgesi yanlis degerleri verecektir dolayisiyla program yanlis yere dönüs yapacaktir. Eger özel bir algoritma olusturulmuyorsa prosedurun basindaki yigin degeri ile RET komutuna ulasan yigin bölgesi degeri ayni olmak zorundadir. Eger ayni olmuyorsa bunu RET komutunun degerini alacagi yeri isaret ederekte yapabiliriz. Normalde RET komutu kendi basina kullanilir. Ancak  asagida oldugu gibi RET komutunun geri dönüs degerlerini "ayarlama" yaparak gösterebiliriz.

RET 0008

Bu komut ile RET komutu geri dönüs degerlerini (adresini) yigin bölgesinin 8 byte öncesinden almaktadir. Yani ESP-8 (yada SP-8) seklinde olmaktadir.

CALL komutu ile çagrilan kod blogundan istenildigi kadar yine CALL komutu kullanilabilir. Ayni kendisinde oldugu gibi çagrilan içsel CALL komutlari yine RET komutu ile çagrildigi yere geri dönecektir.

CALL komutunun en iyi özelliginden birisi prosedur olarak kullanildiginda yaninda yigin bölgesi vasitasiyla parametlerler kullanilabilmesidir. Standart Windows API fonksiyonlarida bu düzene göre çalisirlar.

CALL Fnt,param1,param2,param3,......

gibi. Bu durumda parametreler sirasiyla yigin bölgesine atilirlar ve çagrim yapilan yerde istenildigi gibi kullanilirlar. Derleyiciler prosedur sonunda RET komutunun yanina otomatik olarak parametre sayisi kadar düsüs degeri koyar ve dönüsümün dogru yere olmasini saglar.


        xor eax,eax
xor ebx,ebx
        call denemeproc,1,2,3
        ......                                

denemeproc proc   p1:dword, p2:dword, p3:dword

         mov eax,p1
         mov ebx,p2
         add eax,ebx
         imul eax,eax,p3
        ret
denemeproc    endp

Bu örnekte denemeproc isimli prosedur (kod blogu) 1,2,3 sayilari ile çagriliyor. Prosedürün basina gelince yigin bölgesinde CS, EIP, 1,2,3 degerleri olacaktir. Prosedurde bu degerleri kullanmak için hepsine bir simge veriyoruz.Burada p1,p2,p3 gibi. Sonra bunlarin degerlerini veriyoruz ki prosedur içinde dogru kullanilim olussun. Islem yapiliyor ve sonuçta bir EAX degeri olusuyor. Tekrar belirtmem gerekirse burasi tamamen programcinin hakimiyetinde, sonuçta mutlaka EAX register olmak zorunda degil. Ayni sekilde parametre sayisi ve degisken isimleride tamamen kullanicinin kontrolündedir. Ben burada örneklemek için bu degerleri ve registerleri kullandim. Prosedure (kod blogu) RET komutu ile bitiyor ve geri dönüs basliyor. Biz burada sadece RET komutunu vererek yigin bölgesi - atlama bölgesi dogrulamasini derleyiciye birakiyoruz. Ancak herhangi bir debugger ile bakinca burada RET komutunun yaninda 000Ch degerinide görecegiz. Yani RET 000Ch olacaktir. Geri dönüsüm islemi benim örnekte ..... seklinde belirttigim yere olacaktir. Yani çagrilan komutun sonrasina.

Yigin üzerinde atlama yapmak

Bu standart bir islem degildir. Sadece programcilarin kullandigi ve güzel bir yöntemdir. Bu yöntem RET komutunun geri dönüs için yigin bölgesini kullanmasi esasina dayanir. Herhangi bir register yada herhangi bir deger yigin bölgesine atilir (PUSH ile yada direkt olarak MOV [ESP+4],deger gibi) Daha sonra RET komutu uygulanarak istenilen adrese dönmesi saglanilir.

        mov eax,401000h
        push eax
        ret

Bu örnekte görüldügü gibi EAX registere 401000 degeri veriliyor ve PUSH EAX ile yigina atiliyor. Sonra RET komutu uygulaniyor. RET komutu dogrudan yigin bölgesindeki 401000 degerini alacak ve o adrese dönüsüm yapacaktir. Bu islem register kullanmadan da asagidaki gibi kisaca yapilabilir:

push 401000h
ret

Bu dönüsüm sonunda elbette yigin bölgesinden çagrim adresinin degeri düsülerek ESP (ve SP) register degeri degisecektir.
Ben bu yöntemi daha çok grup eslemeleri ile kullaniyorum. Yani beser byte aralikli atlama tablosu olusturup yapilan matematiksel isleme göre (offset degerini toplayarak) atlamayi sagliyorum. Sizlerde kendiniz böyle kisa ve yararli yöntemler gelistirebilirsiniz.

CALL FAR ve IRET komutu

Her ne kadarki Windows ortaminda CALL FAR SEG:OFT seklinde bir komuta rastlamamis olsanizda bu çagrim sekli gerçek modda yani DOS ortaminda bir hayli önemlidir. En çok kullanildigi alan daha önce bahsettigim TSR' ler konusundadir. Buna göre CALL komutu baska bir segmentte bir offseti çagirmakta ve yigin degerlerini buna göre saklamaktadir. Korumali modun yapisindan dolayi bu komutun korumali modda pek kullanma ihtiyaci duymayiz fakat sistemde yüksek düzeyli interrupt programlamarinda kullanilmaktadir.Gerçek modda ise (DOS) interrupt vektörlerinin alinan ve baska bir yere yönlendirilen (hook edilen) interrupt'un (kesme) vektör degerleri mutlaka sisteme geri dönüs yapmak (callback) zorundadir. Yoksa sistem kararsiz duruma düserek kilitlemeye, resetlenmeye neden olacaktir. Bunun için vektör degerleri mutlaka tutulup interrupt rutini sonunda çagrilmalidir. CALL FAR komutu bunu tek ve komut olarak saglar. Ayrica yeri gelmisken belirtmekte yarar var, normal CALL çagrim islemlerinin geri dönüsümü saglayan RET komutu yerine IRET komutu tahsis edilmistir. IRET komutunun RET komutundan en büyük farki yigin bölgesine CS, IP registerden baska FLAG (bayrak) registeride atmasidir. IRET komutu korumali modda IRETD olarak kullanilir ve bu 32 bitlik IRET komutu demektir.

JMP FAR Komutu

JMP FAR komutuda CALL FAR komutu gibidir kullanilisi aynidir. Ancak CALL FAR gibi geriye dönüsü yoktur. JMP komutu daha önce anlattigim gibi sartsiz ve direkt atlama yapar ve islem oradan itibaren devam eder.  

Mantiksal komutlar ve islemleri

Lisede mantik isimli bir ders gördük. Isin içinde not olunca ögrenme istegimiz yapaylassada mantik dersi matematik gibi önemli bir dersdi. Bu dersde bir önerme sonunda sonuc vardir yada yoktur seklince bir genel bir tanim vardir. Bu mantigin temelini olusturur ve yine "üçüncü hali imkansizligi" gibi genel bir teoriyide kapsar. Iste bilgisayarlarda bilgi alis-verisini ve çalisma prensiplerini hep bu temel üzerine oturmustur. Bilgisayarda mantik denilince aklimiza ikili sayi sistemi gelmeli çünkü makina kodunda mantik komutlari ve islevleri hep bitler üzerinde olur. Daha önceki konularda bahsettigimiz gibi 8 bit 1 byte etmekte. Kisaca bir sayi, sembol yada harf 8 tane 1 veya 0 'dan (yada sadece birisinden) olusur. Bitler üzerinde yapilan islemler dogal olarak sayinin degerinde de degisklige yol açacaktir. Biti setlemek (1 yapmak) yada resetlemek (sifirlamak) aslinda toplama ve çikarma islemleri gibidir. Toplama ve çikarma islemleride asil olarak bitler üzerinde degisiklik yaparak islevlerini gerçeklestiririz. Tabi olarak mantiksal islemlerin sonuçlari toplama çikarma islemlerini sonuçlari ile ayni degildir, her mantiksal komutun farkli sartlari vardir ve sonuçlar bu kurallara göre tayin olur.

Mantiksal islemlerde VE, VEYA, DEGIL, VEYA DEGIL gibi mantik karsilastirmalari vardir. Bunlar assemblerda AND, OR, XOR, NOT komutlariyla islevlerini gerçeklestirirler. Buradaki amaç en iyi seçenekleri bulmak ve istenildigi sekilde gruplama yapabilmektir.

AND mantiksal komutu

AND komutu asagida verdigim tabloya göre karsilastirma yaparak bitleri setler yada resetler. Bu islem birisi asil sayi digeri hedef sayi olmak üzere iki sayinin AND islemine tabi tutulmasi ile olur. Bütün mantiksal islemlerde oldugu gibi AND isleminde de sonuc hedef sayiya yüklenir. AND komutu register-register, register -adres, adres- register seklinde aynen matematiksel toplama ve çikarma komutu gibi adreslenebilir. Ancak bu islemin adreslerle ilgili olmayip matematiksel - mantiksal oldugunu unutmayalim. Asagidaki liste diger mantiksal komutlar içinde geçerlidir.

and al,bl ; register-register
and eax,1234 ; register - sayi
and dword ptr [label1],9876 ; adres-sayi
and dword ptr [label1],edx ; adres - register

gibi birden çok kullanilim seçenegi mevcuttur. Simdi AND komutunun tablosunu inceleyelim. Yukaridan asagiya dogru siralama yaptim.


AND Mantiksal Tablosu
 

ASIL

1

1

0

0

HEDEF

1

0

1

0

SONUC

1

0

0

0

Bu tabloda gördügünüz gibi asil ile hedef 1 veya 0 olarak ikili sistemde deger aliyorlar. Bu degerlere göre AND islemi karsilastirma yapiyor.

asil deger 1 ise ve hedef degerde 1 ise sonuc 1 olacaktir.
asil deger 0 ise ve hedef degerde 1 ise sonuc 0 olacaktir.
asil deger 1 ise ve hedef degerde 0 ise sonuc 0 olacaktir.
asil deger 0 ise ve hedef degerde 0 ise sonuc 0 olacaktir.


Örnek :

mov eax,0ffh ; eax = 0ffh = 11111111b
mov ebx,0aah ; ebx = 089h = 10001001b
and eax,ebx ; eax = 089h = 10001001b

yukaridaki tabloyu dikkate alarak incelerseniz 1-1 olanlarin sonuçlari 1; digerlerinin sonuçlarinin 0 oldugunu görürürüz.

OR Mantiksal Komutu

OR mantiksal komutu AND mantiksal komutuna göre biraz daha genis açilidir. Yukaridaki tabloda görüldügü gibi AND islevi ancak iki bitinde 1 (set) olmasi durumuda 1 oluyor. Ancak OR mantiksal isleminde sadece ikisi 0 (reset) ise sonuç 0 olacaktir. Diger durumlarda sonuc hep 1 olacaktir. Tabloyu yukaridan asagiya dogru inceleyin.


 

OR Mantiksal Tablosu

ASIL

1

1

0

0

HEDEF

1

0

1

0

SONUC

1

1

1

0

Örnegin:

mov eax,12345678h ; eax = 12345678h = 00010010001101000101011001111000b
mov ebx,87654321h ; ebx = 87654321h = 10000111011001010100001100100001b
or eax,ebx ; eax = 97755779h = 10010111011101010101011101111001b

örnegin yukaridaki tablodan bakarak incelerseniz sadece iki bitin reset (0) olmasi durumunda 0 oldugu görülür. Diger durumlarda sonuç daima 1 (set) olacaktir.

XOR Mantiksal Komutu

XOR mantiksal komutu mantiksal komutlar içinde nerdeyse en çok bilinendir. Genelde sifreleyiciler, paketleyiciler gibi koruma uygulamalarinda XOR ile degerleri degistirmek yada paket için tablo olusturmak alisilagelmistir. Bu veya diger komutlar kesinlikle CPU tasariminda yalnizca sifreleme yada paketleme gibi islemler için tasarlanmamistir. Bu tamamen programcilarin tercihidir. XOR mantiksal komutu OR komutunun özel bir seklidir. Bu mantiksal komutta sart eger asil bit ile hedef bit ayni ise sonuç 0 (reset); farkli ise sonuç 1 (set) olur. Buna göre XOR islemine tabi tutulan bitlerin ikiside 1 veya 0 ise sonuç daima 0 olacaktir. Eger farkli ise sonuç 1 olacaktir.

XOR Mantiksal Tablosu

ASIL

1

1

0

0

HEDEF

1

0

1

0

SONUC

0

1

1

0

Örnegin:

mov eax,12345678h ; eax = 12345678h = 00010010001101000101011001111000b
mov ebx,87654321h ; ebx = 87654321h = 10000111011001010100001100100001b
xor eax,ebx ; eax = 95511559h = 10010101010100010001010101011001b

NOT Mantiksal komutu

NOT komutu "degil" anlamina gelir. Bunu bitlerin degili olarak düsünürsek 1 ise 0 ; 0 ise 1 demek oluyor. Yani tersine bitleri tam tersine çevirmis oluyoruz. Bu komut iki deger ile birlikte degilde dogrudan hedef üzerinde islem yapar. Bunun için basta belirttigim adresleme seklide sadece NOT Register seklini alir. Bu komutun asil sayisi ile sonuç sayisi toplanirsa ortaya en yüksek sayi çikar. Asagidaki örnekte 32 bitlik bir islem oldugu için sonuç 0ffffffffh olacaktir.

NOT Mantiksal Tablosu

ASIL

1

0

SONUC

0

1

Örnegin :

mov eax, 12345678h ; eax = 12345678h = 00010010001101000101011001111000b
not eax ; eax = EDCBA987h = 11101101110010111010100110000111b
12345678+edcba987 = 0ffffffffh

NOT EAX isleminden sonra sayinin bitlerini tam tersine döndügüne dikkat edin.

NEG Mantiksal komutu

NEG komutu negatife çevirme yapmak için kullanilir. NEG komutuda NOT gibi register ile dogrudan kullanilir. Bu islem sonucunda CPU sonuç sayisini C bayragi ile toplanarak tamamlama yapilir. Bunun için asil sayi ile hedef sayiyi birbirleriyle toplarsak sonuç daima 0 olur.

NEG Mantiksal Tablosu
 

ASIL

1

0

SONUC

0

1

Örnegin :

mov eax, 12345678h ; eax = 12345678h = 00010010001101000101011001111000b
not eax ; eax = EDCBA988h = 11101101110010111010100110001000b
12345678h+edcba988h = 0

Mantiksal Bit çevirme ve kaydirma komutlari

Bit çevirme ve kaydirma komutlari pek çok alanda kullanilir. Grafiksel islemlerde, çevrim islemlerinde, sayaçlarda,... Bit kaydirma kendi arasinda kaydirma komutlari ve çevirme komutlari olarak ikiye ayrilir. Kaydirma komutlarida aritmetik ve logical olarak ikiye ayrilirlar. Bunlarin arasinda islevsel bir farklilik vardir. Kaydirma komutlari biti sonuç 0 oluncaya kadar saga yada sola dogru kaydirir. Kaydirilan bit yokolur ve tersine islem yapilsa bile geriye dönemez. Çevirme komutlari ise bitleri çevirerek dönüsüm yapar ve bit sayisina bagli olarak tekrar eski degerine ulasir. Çevirme komutlarinda hiçbir bitin degeri kaybolmaz. Daima çevrimiçi olarak kalir. Iki komut grubunda da saga ve sola kaydirma mevcuttur ve ingilizcedeki left, right kelimelerinin basharfleri ile belirtilirler. Bu komutlar yardimci register ile kullanilarak blok kaydirma veya çevirme islemlerine tabi tutulabilirler. Yardimci register degismez olarak CL registerdir ve burada bir sayaç görevini üstlenir. Registerdeki sayinin bitini su kadar kaydir diye komut verebiliriz. Özellikle aritmatiksel kaydirma komutlari register-register kullanilimi ile kaydirmak islevine sahiptirler. Burada kaydirma sayisi registeri 0-31 sayilari olmak zorunda çünkü su
anda bu komutlar en fazla 32 bitlik registerleri kullanabiliyor.

Mantiksal kaydirma ve çevirme komutlari bildigimiz matematiksel bölme ve çarpma islemlerinin aynisi yaparlar. Saga dogru yapilirsa çarpma, sola dogru yapilirsa bölme isleminin aynisini yapmis olurlar.

Asagidaki örnekler ile sanirim bunlar daha iyi anlasilacak.

Mantiksal kaydirma komutlari

Örnek olarak elimizde eax registerde 00111000 seklinde bir sayimiz var. Bu sayiyi 1 bitlik kaydirma islemine tabi tutuyoruz:

mov eax,00111000 ; eax = 00111000
shl eax,1 ; eax = 01110000

shl eax,1 komutu ile eax registerdeki bitleri sola dogru (shl= sola , shr = saga) kaydirdik. Örnektede görüldügü gibi ilk bit 0 oldu ve ilk set olan bit sola dogru kaydi. Sonuçta sayinin degeri iki katina çikmis oldu. Çü
nkü basamak atladi.

Eger biz bu islemi 5 kere daha yaparsak bütün bitler sola dogru kayacagi ve yerlerin resetleyecegi için sonuç 0 olacaktir. Yani sayi döngü içinde mutlaka 0 degerine ulasacaktir. Buradaki 0 degeri olarak bahsettigim bitlerin tamaminin sifirlanmasi ve sayinin degerini tamamen kaybetmesi oluyor.

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


Eger sayiya shr islemine (saga kaydirma) tabi tutarsak:

shr eax,1 ; 0111000
0 ->
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 ->

Görüldügü gibi sonuç eger sayinin toplam biti kadar yapilirsa saga yada sola olm
asi farketmezsizin daima 0 olacaktir.

Aritmatik kaydirmalara örnek vermek gerekirse:

mov ax,1234 ; ax = 1234
mov cl,4 ; Kaç bitlik kaydirma islemi yapacak?
sar ax,cl ; saga dogru kombine 4 bit kayacak


Diger bir örnek :

mov ax,9978
mov cl,7
sal ax,cl ;
sola dogru 7 bit kaydirilir.

Ayni sekilde SHR ve SHL komutlarida yardimci register olmadan yanina verilen parametre kadar kaydirilabilir.

mov ax,4523
shr ax,5

yada

mov eax,9742
shl eax,2

Ayrica 64 bitlik islemler için SHLD ve SHRD komutlarida vardir
. Bunlar ayni SHL ve SHR seklinde çalisir ancak bit alanlari 64 bite kadar çikar.

Mantiksal Döndürme komutlari

Mantiksal döndürme komutlari ayni kaydirma komutlari gibi bitleri saga yada sola kaydirir yalniz bitlerin degeri kaybolmaz her kayan bitin yerine bir önceki bit gelir. Son bit ilk bir ile yer degistirir veya ilk bir son bit ile yer degistirir. Eger döndürülecek registerin degeri 0 degilse ve degerini yokedecek baska bir islem yapilmiyorsa degeri asla 0 olmaz. Çevrimi bir daire gibi düsünebiliriz.
Ayni dünyanin günes etrafinda dönüsü gibi belli bir süre sonra bitler tekrar ayni yerlerine gelecektir. Yine kaydirma komutari gibi tek tek yada yardimci register vasitasiyla birden fazla kombine çevrim mümkündür.

Örnegin:

mov ax,0111000 ; eax = 1110000

rol ax,1 ; eax = 1100001

görüldügü gibi bastaki bit sola dogru çevrilir ve tasan bir ilk bitin yerine koyulur.

mov ax,0111000 ; 0111000 <-
rol ax,1 ; 1100001 <-
rol ax,1 ; 1000011 <-
rol ax,1 ; 0000111 <-

tam terside yapilabilir.

mov ax,0111000 ; 01110
00 ->
ror ax,1 ; 0011100 ->
ror ax,1 ; 0001110 ->
ror ax,1 ; 0000111 ->

Ayrica RCR ve RCL çevirme komutlarida CL register ile kombine kullanilir. Islevleri aynidir ancak C bayragi ile birlikte kullanilir. Bu sayede döndürme islemini bayrak bazinda kont
rol altina alabiliriz. Örnegin döndürülen sayinin 0 olmasi durumda.

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

yada

mov ax,0111000
mov cl,5
rcr ax,cl

gibi rahatça kullanabiliriz.


 

EkleBunu Sosyal Paylaşım Butonu

Yorum yaz! :: Arkadaşına Gönder!

0 yorum yazılmıştır

« Önceki :: Sonraki »

Reklamlar