İşartli sayılarda karşılaştırma nasıl yapılır?
İşaretsiz sayılarda doğrudan flag register'ları kontrol ederek karşılaştırma yapabildiğimiz gibi işaretli sayılarda da karşılaştırma yapılabilir fakat yine doğrudan flag register'ları kontrol etmek yerine JG, JGE, JL ve JLE gibi talimatları kullanmak daha yararlı. Nedenini yorum satırlarında detaylı açıkladım.
İşaretsiz sayılarda doğrudan flag register'ları kontrol ederek karşılaştırma yapabildiğimiz gibi işaretli sayılarda da karşılaştırma yapılabilir fakat yine doğrudan flag register'ları kontrol etmek yerine JG, JGE, JL ve JLE gibi talimatları kullanmak daha yararlı. Nedenini yorum satırlarında detaylı açıkladım.
; İşaretsiz karşılaştırmaların hepsi SUB, JC, JNC ve JZ komutları ile de yapılabilir.
; İşaretli karşılaştırmaların da hepsi SUB, JO, JNO, JS, JNS ve JZ komutları ile de yapılabilir.
; Karşılaştırmalarda CMP ile SUB komutu arasındaki fark çıkarma işleminin sonucunu register'da saklayıp saklamamasıdır.
; CMP komutu sonucu register'da saklamadığı için daha çok tercih edilen odur.
; İşaretli ve işaretsiz karşılaştırmalarda BüyükEşit, KüçükEşit gibi karşılaştırmaları yapabilmemiz için 2 tane Flag'i kontrol etmemiz ve ona göre sonucu belirlememiz gerekiyor.
; Yani örneğin işaretsiz karşılaştırmada BüyükEşit veyada KüçükEşit karşılaştırması yaparken Carry Flag(Büyüklük-Küçüklük için) ve Zero Flag(Eşitlik için ) kontrol edilmeli.
; İşaretli karşılaştırmada BüyükEşit veyada KüçükEşit karşılaştırması yaparken Büyüklük-Küçüklük için Overflow ve Sign flag'leri ve Zero Flag(Eşitlik için) kontrol edilmeli.
; Ve bu da kodun okunurluğunu azaltmakla birlikte karşılaştırma işlemini kullanışsız hale getiriyor.
; Çözüm olarak işaretsiz sayılar için JA, JAE, JB ve JBE komutları, işaretli sayılar için ise JG, JGE, JL ve JLE komutları var.
; "İŞARETLİ" sayılarda karşılaştırma yaparken JO, JNO, JS, JNS ve JZ gibi talimatlar yerine JG, JGE, JL ve JLE talimatlarda kullanılabilir.
; Bu komutlarda JO, JNO, JS, JNS ve JZ'nin yaptığı gibi bayrakların durumlarını kontrol edip ona göre atlıyor yada atlamıyor.
; Fakat JG, JGE, JL ve JLE komutlar daha pratik ve kullanışlı. Çünkü bu komutlar ile çok az daha yüksek seviyeden kod yazmış oluyoruz.
; Assembly'de bir fonksiyon belki onlarca farklı kez ifade edilebilir.
; İşte bu noktada en pratik ve en kullanışlı olanı kodlamak bizim elimizde.
; Bu programda işaretli sayılarda karşılaştırma yağacağım. İşaretli karşılaştırmalarda Overflow, Sign ve Zero flag'leri nasıl değişiyor bakalım.
; cmp eax,ebx
; Çıkarma işleminin sonucunda taşma olabilir veya olmayabilir. İki durumuda ayrı ayrı ele alalım.
; Eğer çıkarma işleminin sonucunda taşma yoksa çıkarma işleminin sonucu doğrudur yani OF = 0'dir.
; SF = 1 ise EBX > EAX'dir.
; SF = 0 ise EAX > EBX'dir.
; Eğer çıkarma işleminin sonucunda taşma varsa çıkarma işleminin sonucu yanlıştır yani OF = 1'dir
; Overflow olması bizim çıkarma işlemimizin işaretini yanlış verir ve bunun sonucunda karşılaştırmada yanlış olur.
; Yani OF = 1 ise sonucumuz: ya negatif olması gerekirken pozitif ya da pozitif olması gerekirken negatif gelmiştir.
; Yaniii:
; Taşma sonucunda SF = 1 olmuş ise doğru sonuçta SF = 0'dır. SF = 0 ise EAX > EBX'dir.
; Taşma sonucunda SF = 0 olmuş ise doğru sonuçta SF = 1'dir. SF = 1 ise EBX > EAX'dir.
; Kısa bir pratik olarak: SF = OF ise EAX > EBX'dir.
; Yani taşmann olduğu durumda SF = 1 ise veya taşmanın olmadığı durudma ise SF = 0 ise EAX > EBX'dir.
; Zero Flag'de değişen bir şey yok çıkarma işleminin sonucu 0 ise EAX = EBX'dir. Bu durumda ZF = 1 olur.
; JG : Jump if greater. [(SF=0 ve OF=0) veya (SF=1 ve OF=1)] EAX > EBX ise atla.
; JGE : Jump if greater or equal. [(SF=0 ve OF=0) veya (SF=1 ve OF=1) veya (ZF=1)] EAX >= EBX ise atla.
; JL : Jump if less. [(SF=1 ve OF=0) veya (SF=0 ve OF=1)] EAX < EBX ise atla.
; JLE : Jump if less or equal. [(SF=1 ve OF=0) veya (SF=0 ve OF=1) veya (ZF=1)] EAX <= EBX ise atla.
.386
.model flat
.code
start PROC
mov eax,5
mov ebx,7
; eax - ebx = 0101b - 0111b = 5 - 7 = - 2
; -7 = 1001b (Two's complement)
; 0101b
; + 1001b
; -----------
; 1101b (Two's complement) = - 2 ===> SF = 0
; İşlemin sonucunda bayraklar bu şekilde ayarlanır: SF = 1, OF = 0, ZF = 0
; SF = 1, OF = 0 ise EBX > EAX sonucuna ulaşırız.
cmp eax,ebx
jl ebx_daha_buyuk
jz eax_ve_ebx_esit ; Eğer eşitlerse çıkarma işleminin sonucu sıfırdır. Zero Flag = 1 olur.
jg eax_daha_buyuk
eax_daha_buyuk:
mov ecx,eax ; eax, ebx'den büyük ise ecx = eax olsun.
jmp bitti
eax_ve_ebx_esit:
mov ecx,eax ; eax ve ebx birbirine eşit ise ecx = ebx = eax olsun.
jmp bitti
ebx_daha_buyuk:
mov ecx,ebx ; ebx, eax'den büyük ise ecx = ebx olsun.
; Yani hangisi büyük ise ecx'e büyük olanın değeri taşınacak. Eşitler ise ecx'de aynı değer taşınacak.
bitti:
ret
start endp
end startBu içeriği görmek için giriş yapın.