Bölüm 6: Aritmetik ve Mantıksal İşlemler
Giriş
Öğrenme Çıktıları
Bir işlemin sonucuna göre CF, ZF, SF, OF, PF ve AF bayraklarının değerini hesaplamak; CF ile OF farkını açıklamak.
Toplama, çıkarma, karşılaştırma, mantıksal, çarpma, bölme ve tek işlenenli komutları doğru işlenenlerle kullanmak.
MUL, IMUL, DIV, IDIV'in örtük yazmaçlarını (AL, AX, DX:AX) ve bölme hatasını bilmek.
Dizi toplama, BCD düzeltme ve sıcaklık dönüşümü programlarını adım adım izlemek.
Bayrak Yazmacı
Aritmetik ve Mantık Komutları
- Aritmetik ve mantık komutlarının sonuçları, işlemcinin durum bayraklarını etkiler.
- Bayraklar, 16 bitlik FLAGS yazmacında tutulur; her bit 0 ya da 1 olan bir bayraktır.
- 8086'da bu 16 bitin 9'u kullanılır: 6 durum bayrağı (sonucu anlatır) ve 3 denetim bayrağı (işlemcinin davranışını yönetir).
- Koşullu atlamalar (
JZ,JC,JO…) bu bayraklara bakarak karar verir.
Kesik çizgili bitler 8086'da kullanılmaz.
Bayrak Yazmacı
Bayraklar Tablosu
| Bit | Bayrak | Tür | 1 olur, eğer… |
|---|---|---|---|
| 0 | CF · Carry | durum | işaretsiz taşma: toplamada elde, çıkarmada ödünç oluştu |
| 2 | PF · Parity | durum | sonucun düşük baytında çift sayıda 1 biti var |
| 4 | AF · Auxiliary | durum | bit 3'ten bit 4'e elde/ödünç oluştu (BCD için) |
| 6 | ZF · Zero | durum | sonuç sıfır |
| 7 | SF · Sign | durum | sonucun en anlamlı biti (MSB) 1 |
| 8 | TF · Trap | denetim | her komuttan sonra INT 1 (tek adım hata ayıklama) |
| 9 | IF · Interrupt | denetim | INTR kesmeleri kabul edilir (STI / CLI) |
| 10 | DF · Direction | denetim | dizgi komutları geriye doğru (STD / CLD) |
| 11 | OF · Overflow | durum | işaretli taşma: sonuç işaretli aralığa sığmadı |
Bayrak Yazmacı
CF ve ZF
- İşaretsiz bir taşma olduğunda 1 olur.
- Ör. bayt toplama 255 + 1 = 256: sonuç 0…255 aralığında değil → AL = 00h, CF = 1.
- Çıkarmada ödünç alınınca da 1 olur: 7 − 9 → CF = 1.
- Taşma yoksa 0.
STC,CLC,CMCile doğrudan değiştirilebilir.
- Sonuç sıfır ise 1 olur.
- Sıfır olmayan sonuçta 0.
- Ör.
SUB AL, AL→ ZF = 1. CMP AX, BXsonrası ZF = 1 ise AX = BX.- Dikkat: ZF = 1 “sonuç sıfır” demektir, “bayrak yanlış” değil.
MOV AL, 255 ADD AL, 1 ; AL = 00h, CF = 1, ZF = 1
Bayrak Yazmacı
SF, OF ve PF
Sonuç negatif ise 1, pozitif veya sıfır ise 0. Aslında sonucun en anlamlı bitinin (MSB) kopyasıdır.
İşaretli bir taşma olduğunda 1. Ör. 100 + 50 = 150; sonuç −128…127 aralığında değil → AL = 96h (−106), OF = 1.
Sonucun düşük 8 bitinde 1'lerin sayısı çift ise 1, tek ise 0. Sonuç sözcük olsa da yalnızca düşük bayta bakılır.
MOV AL, 100 ADD AL, 50 ; AL = 96h: SF = 1, OF = 1, CF = 0, PF = 1
Bayrak Yazmacı
AF, IF, DF ve TF
Düşük nibble'dan (4 bit) yüksek nibble'a işaretsiz taşma olduğunda 1. Yalnızca BCD düzeltme komutları (AAA, AAS, DAA, DAS) kullanır.
08h + 08h = 10h → AF = 1.
1 iken CPU, harici aygıtlardan gelen (INTR) kesmelere tepki verir. STI → 1, CLI → 0. NMI'yi etkilemez.
Dizgi (string) komutları bu bayrağı kullanır: 0 iken SI/DI artar (ileri), 1 iken azalır (geri). CLD / STD.
1 iken işlemci her komuttan sonra INT 1 üretir. emu8086'daki “single step” gibi hata ayıklayıcılar bu mekanizmayı kullanır.
Bayrak Yazmacı
CF mi, OF mi?
İşlemci toplamayı yalnızca bitler üzerinde yapar; yorum programcınındır. CF işaretsiz, OF işaretli yorumda sonucun doğru olup olmadığını söyler.
| AL + işlenen | işaretsiz yorum | işaretli yorum | AL | CF | OF |
|---|---|---|---|---|---|
FFh + 01h | 255 + 1 = 256 | -1 + 1 = 0 | 00h | 1 | 0 |
64h + 32h | 100 + 50 = 150 | 100 + 50 = 150 | 96h | 0 | 1 |
C8h + 64h | 200 + 100 = 300 | -56 + 100 = 44 | 2Ch | 1 | 0 |
80h + 80h | 128 + 128 = 256 | -128 + -128 = -256 | 00h | 1 | 1 |
05h + 0Ah | 5 + 10 = 15 | 5 + 10 = 15 | 0Fh | 0 | 0 |
Bayrak Yazmacı
ADD ile Bayraklar Adım Adım
MOV AL, 64h (100) ve ADD AL, 32h (50). Bitler sağdan sola toplanır.
Sonuç 96h = 1001 0110b. İşaretsiz yorumla 150 (doğru), işaretli yorumla −106 (yanlış!).
CF: en soldaki bitten dışarı elde çıktı mı? Hayır → CF = 0 (150 ≤ 255).
OF: iki pozitif sayının toplamı negatif çıktı (bit 7'ye giren ve çıkan elde farklı) → OF = 1.
SF = sonucun bit 7'si = 1. Sonuç sıfır değil: ZF = 0.
PF: 1001 0110b'de dört tane 1 → çift → PF = 1. AF: düşük nibble'lar 4 + 2 = 6, elde yok → AF = 0.
Sonuç: AL = 96h; CF = 0, ZF = 0, SF = 1, OF = 1, PF = 1, AF = 0.
Bayrak Yazmacı
Demo: Bayrak Hesaplayıcı
İki değer ve bir komut seçin. Değerler onluk (-5), onaltılık (3Fh) veya ikilik (1010b) yazılabilir.
Komut Grupları
Komutlar Üç Gruba Ayrılır
ADD, SUB, CMP, AND, TEST, OR, XOR
hedef, kaynak
MUL, IMUL, DIV, IDIV
tek işlenen + örtük AL / AX / DX
INC, DEC, NOT, NEG
işlenen hem kaynak hem hedef
Komut Grupları
Komutların Anlamı
| 1. grup | Ne yapar? |
|---|---|
ADD | iki değeri toplar, sonucu hedefe yazar |
SUB | kaynağı hedeften çıkarır, sonucu hedefe yazar |
CMP | çıkarır ama sonucu saklamaz; yalnız bayraklar |
AND | bit düzeyinde VE |
TEST | bit düzeyinde VE; sonucu saklamaz |
OR | bit düzeyinde VEYA |
XOR | bit düzeyinde dışlayan VEYA |
| 2. grup | Ne yapar? |
|---|---|
MUL | işaretsiz çarpma |
IMUL | işaretli çarpma |
DIV | işaretsiz bölme (bölüm + kalan) |
IDIV | işaretli bölme |
| 3. grup | Ne yapar? |
|---|---|
INC | 1 artırır |
DEC | 1 azaltır |
NOT | tüm bitleri tersler |
NEG | işaretini değiştirir (ikiye tümleyen) |
Grup 1: İki İşlenenli
ADD, SUB, CMP, AND, TEST, OR, XOR: İşlenenler
| Biçim | Örnek |
|---|---|
| REG, memory | ADD AX, [BX] |
| memory, REG | SUB var1, CL |
| REG, REG | XOR AX, AX |
| memory, immediate | AND byte ptr [SI], 0Fh |
| REG, immediate | CMP AL, 'A' |
- REG: AX, BX, CX, DX, AH, AL, BL, BH, CH, CL, DH, DL, DI, SI, BP, SP.
- memory:
[BX],[BX+SI+7], değişken … - immediate:
5,-24,3Fh,10001101b…
ADD [BX], [SI] (iki bellek), ADD AL, BX (boyut farkı), ADD 5, AL (hedef sabit), ADD DS, AX (kesim yazmacı).Grup 1: İki İşlenenli
Kurallar ve Etkilenen Bayraklar
- İki işlenenli işlemlerden sonra sonuç her zaman ilk işlenende (hedef) saklanır.
CMPveTESTyalnızca bayrakları etkiler, sonuç saklamaz.ADD/SUB: ikinci işleneni birinciye ekler / birinciden çıkarır.CMP: ikinci işleneni birinciden çıkarır, sonucu saklamaz.AND/OR/XOR: iki işlenenin karşılıklı bitleri arasında işlem yapar;TEST, AND gibidir ama yalnız bayrakları etkiler.
| Komut | CF | ZF | SF | OF | PF | AF |
|---|---|---|---|---|---|---|
ADD, SUB, CMP | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
AND, OR, XOR, TEST | 0 | ✓ | ✓ | 0 | ✓ | ? |
✓: sonuca göre ayarlanır · 0: her zaman temizlenir · ?: tanımsız. Mantıksal komutlar CF ve OF'yi daima 0 yapar.
Grup 1: İki İşlenenli · Kodu adım adım çalıştır
Kod İzleme: ADD, SUB, CMP
AL = F0h. MOV bayrakları değiştirmez (başlangıçta hepsi 0).
F0h + 20h = 110h; 8 bite 10h sığar, dışarı taşan 1 → CF = 1. İşaretli: −16 + 32 = 16 doğru → OF = 0.
BL = 7. Bayraklar önceki ADD'den kalır.
7 − 9 = −2 = FEh. Ödünç alındı → CF = 1; MSB = 1 → SF = 1. 7 − 9'da düşük nibble ödünç → AF = 1.
CMP AL, 10h: 10h − 10h = 0 → ZF = 1. AL değişmedi: eşitlik böyle sınanır.
FEh − 0: ZF = 0, SF = 1, CF = 0. İşaretsiz FEh > 0, işaretli −2 < 0.
FEh + 2 = 100h → BL = 00h, CF = 1, ZF = 1. İşaretli: −2 + 2 = 0 doğru → OF = 0.
mov al, 0F0h ; 240 add al, 20h ; 240 + 32 = 272 mov bl, 7 sub bl, 9 ; 7 - 9 cmp al, 10h ; AL - 10h cmp bl, 0 add bl, 2 ; FEh + 2
Grup 1: İki İşlenenli · Kodu adım adım çalıştır
ADC ile 32 Bitlik Toplama
32 bitlik ilk sayı DX:AX'e yüklenir: düşük sözcük FFFFh…
…yüksek sözcük 0001h → DX:AX = 0001FFFFh (131071).
İkinci sayı CX:BX = 00020001h (131073).
FFFFh + 0001h = 10000h → AX = 0000h, CF = 1: yüksek sözcüğe taşınacak elde.
ADC = ADD + CF: 0001h + 0002h + 1 = 0004h. Sonuç DX:AX = 00040000h (262144) ✓
; DX:AX = 0001FFFFh, CX:BX = 00020001h mov ax, 0FFFFh mov dx, 0001h mov bx, 0001h mov cx, 0002h add ax, bx ; düşük sözcükler adc dx, cx ; yüksek + CF
SBB (subtract with borrow) aynı fikirle çok sözcüklü çıkarma yapar: önce SUB, sonra SBB.
Mantıksal İşlemler
Mantıksal İşlem Kuralları
| A | B | A AND B |
|---|---|---|
| 1 | 1 | 1 |
| 1 | 0 | 0 |
| 0 | 1 | 0 |
| 0 | 0 | 0 |
İkisi de 1 ise 1.
| A | B | A OR B |
|---|---|---|
| 1 | 1 | 1 |
| 1 | 0 | 1 |
| 0 | 1 | 1 |
| 0 | 0 | 0 |
En az biri 1 ise 1.
| A | B | A XOR B |
|---|---|---|
| 1 | 1 | 0 |
| 1 | 0 | 1 |
| 0 | 1 | 1 |
| 0 | 0 | 0 |
Farklı ise 1.
| A | NOT A |
|---|---|
| 1 | 0 |
| 0 | 1 |
Tersler. Tek işlenenli.
AND AL, BL aslında 8 tane bağımsız VE işlemidir.Mantıksal İşlemler
Maskeleme: AND, OR, XOR, TEST
AND ile bit temizleme: maskede 0 olan bit 5 sıfırlanır, diğerleri korunur → küçük harf büyük olur.
OR ile bit kurma: maskede 1 olan bit 5 kesin 1 olur → büyük harf küçük olur.
XOR ile bit tersleme: maskede 1 olan bit değişir → harfin büyük/küçük hâli yer değiştirir.
TEST ile bit sınama: sonuç 01h ≠ 0 → ZF = 0, yani bit 0 = 1, sayı tek. BL değişmez.
Mantıksal İşlemler
Sık Kullanılan Kalıplar
| Kod | Etki | Neden? |
|---|---|---|
XOR AX, AX | AX = 0, ZF = 1, CF = 0 | MOV AX, 0'dan kısa (2 bayt); bayrakları da temizler |
AND AL, 0Fh | '7' (37h) → 7 | ASCII rakamı sayıya çevirir (yüksek nibble silinir) |
OR AL, 30h | 7 → '7' (37h) | sayıyı ASCII rakama çevirir |
AND AL, 0DFh | 'a' → 'A' | bit 5'i temizler: büyük harf |
OR AL, 20h | 'A' → 'a' | bit 5'i kurar: küçük harf |
TEST AL, 1 | ZF = 0 ise tek | AL değişmeden bit 0 sınanır |
TEST AL, 80h | ZF = 0 ise negatif | işaret biti sınanır |
OR AX, AX | AX değişmez | ZF/SF ayarlanır: AX sıfır mı, negatif mi? |
Mantıksal İşlemler · Kodu adım adım çalıştır
Kod İzleme: AND, OR, XOR, TEST
AL = 'a' = 61h = 0110 0001b.
61h AND DFh = 41h = 'A'. 41h'de iki tane 1 → PF = 1. CF = OF = 0.
41h OR 20h = 61h = 'a'. Üç tane 1 → PF = 0.
61h XOR 20h = 41h = 'A' (bit 5 terslendi).
BL = '7' = 37h (ASCII rakam).
37h AND 0Fh = 07h: artık sayısal 7.
07h AND 01h = 01h ≠ 0 → ZF = 0: sayı tek. BL aynı kaldı.
Kendisiyle XOR → 00h, ZF = 1, PF = 1 (sıfır tane 1, çift).
mov al, 'a' ; 61h and al, 0DFh ; büyük harf or al, 20h ; küçük harf xor al, 20h ; tersle mov bl, '7' ; 37h and bl, 0Fh ; sayı 7 test bl, 1 ; tek mi? xor bl, bl ; BL = 0
Grup 2: Çarpma ve Bölme
MUL ve IMUL
| Komut | İşlenen bayt ise | İşlenen sözcük ise |
|---|---|---|
MUL (işaretsiz) | AX = AL × işlenen | (DX AX) = AX × işlenen |
IMUL (işaretli) | AX = AL × işlenen | (DX AX) = AX × işlenen |
İşlenen: REG veya memory (MUL BL, IMUL word ptr [SI]). 8086'da sabit işlenen yoktur: MUL 5 geçersizdir.
Grup 2: Çarpma ve Bölme
DIV ve IDIV
| Komut | İşlenen bayt ise | İşlenen sözcük ise |
|---|---|---|
DIV (işaretsiz) | AL = AX / işlenen AH = kalan (modulus) | AX = (DX AX) / işlenen DX = kalan (modulus) |
IDIV (işaretli) | AL = AX / işlenen AH = kalan | AX = (DX AX) / işlenen DX = kalan |
MUL / IMUL yalnızca CF ve OF'yi anlamlı ayarlar: sonuç işlenen boyutunu aşarsa (üst yarı gerekliyse) CF = OF = 1. Diğerleri tanımsız.
DIV / IDIV sonrası tüm bayraklar tanımsızdır.
Bölen 0 ise ya da bölüm hedefe (AL / AX) sığmıyorsa işlemci INT 0 üretir (bölme hatası).
IDIV bölümü sıfıra doğru keser; kalan bölünenle aynı işaretlidir.
Grup 2: Çarpma ve Bölme
Çarpma ve Bölme Adım Adım
MOV AL, 200, MOV BL, 3. 200 = C8h, işaretli yorumda −56.
MUL BL: 200 × 3 = 600 = 0258h → AX. Sonuç AL'ye sığmadı (AH ≠ 0) → CF = OF = 1.
Aynı bitlerle IMUL BL: −56 × 3 = −168 = FF58h. Farklı sonuç! −168 bayta sığmaz → CF = OF = 1.
AL = FEh (−2), BL = 5: IMUL BL → −10 = FFF6h. AH yalnızca AL'nin işaret uzantısı → CF = OF = 0: sonuç AL'ye sığdı.
DIV BL: AX = 23, BL = 5 → bölüm AL = 4, kalan AH = 3. Yeni AX = 0304h.
IDIV BL: −23 / 5 → bölüm AL = FCh (−4), kalan AH = FDh (−3). Kontrol: −4 × 5 + (−3) = −23.
AX = 1000h (4096), DIV BL (2): bölüm 2048 AL'ye sığmaz → bölme hatası, INT 0. Sözcük bölme (DX:AX / BX) gerekirdi.
Grup 2: Çarpma ve Bölme
Bölmeye Hazırlık: CBW, CWD
- Bölme, işlenenin iki katı genişlikte bir bölünen ister: bayt bölmede AX, sözcük bölmede DX:AX.
- İşaretsiz bölmeden önce üst yarı sıfırlanır:
MOV AH, 0veyaXOR DX, DX. - İşaretli bölmeden önce işaret genişletilir:
CBW(AL → AX),CWD(AX → DX:AX). - DX'i unutmak klasik hatadır: DX'te kalan eski değer bölüneni büyütür ve bölme hatasına yol açabilir.
; işaretsiz: 1000 / 7 mov ax, 1000 xor dx, dx ; DX:AX = 1000 mov bx, 7 div bx ; AX = 142, DX = 6 ; işaretli: -1000 / 7 mov ax, -1000 cwd ; DX = FFFFh idiv bx ; AX = -142, DX = -6
Grup 2: Çarpma ve Bölme
Demo: Çarpma / Bölme Hesaplayıcı
Komutu, boyutu ve değerleri seçin; sonucun hangi yazmaçlara yazıldığını görün. Bölmede bölünen, bayt için AX; sözcük için DX:AX'tir.
Grup 3: Tek İşlenenli
INC, DEC, NOT, NEG
- İşlenenler: REG (AX, BX, … SP) veya memory (
[BX],[BX+SI+7], değişken). Sabit olamaz. INCveDECyalnızca ZF, SF, OF, PF, AF'yi etkiler; CF'ye dokunmaz.NOThiçbir bayrağı etkilemez! İşlenenin her bitini ters çevirir (bire tümleyen).NEGCF, ZF, SF, OF, PF, AF'yi etkiler. İşleneni negatif yapar (ikiye tümleyen): her biti tersler, ardından 1 ekler. Ör. 5 → −5, −2 → 2.
| Komut | CF | ZF | SF | OF | PF | AF |
|---|---|---|---|---|---|---|
INC, DEC | — | ✓ | ✓ | ✓ | ✓ | ✓ |
NOT | — | — | — | — | — | — |
NEG | ✓ (işlenen ≠ 0 ise 1) | ✓ | ✓ | ✓ | ✓ | ✓ |
—: değişmez. INC/DEC'in CF'yi korması, döngü içinde ADC ile çok baytlı toplama yaparken sayaç artırmayı mümkün kılar.
Grup 3: Tek İşlenenli
NEG: İkiye Tümleyen Adım Adım
x = 5 = 0000 0101b.
NOT: her bit terslenir → 1111 1010b = FAh (−6). Bire tümleyen.
+1: FBh = 1111 1011b = −5. NEG bu iki adımı tek komutta yapar; CF = 1 (x ≠ 0).
x = FEh (−2): NOT → 01h, +1 → 02h. Negatifin negatifi pozitiftir.
Özel durum: x = 80h (−128). NOT → 7Fh, +1 → 80h: +128 bayta sığmaz → OF = 1.
x = 0: sonuç 0, CF = 0 (NEG'de CF = 1 olmayan tek durum), ZF = 1.
Grup 3: Tek İşlenenli · Kodu adım adım çalıştır
Kod İzleme: INC, DEC, NOT, NEG
AL = FFh (255 / −1).
FFh + 1 = 00h, ZF = 1. ADD olsaydı CF = 1 olurdu; INC CF'yi değiştirmez → CF = 0 kaldı.
00h − 1 = FFh, SF = 1. Ödünç olsa da CF yine değişmedi.
BL = 7Fh = +127, en büyük pozitif bayt.
7Fh + 1 = 80h = −128: işaretli taşma → OF = 1, SF = 1.
NOT: 80h → 7Fh. Bayraklar hiç değişmedi (SF hâlâ 1 görünüyor).
NEG: −127 = 81h. CF = 1 (işlenen ≠ 0), SF = 1, OF = 0.
mov al, 0FFh inc al ; FFh + 1 dec al ; 00h - 1 mov bl, 7Fh ; +127 inc bl ; +128 ? not bl neg bl
Örnek: Dizi Toplama
Dizi Elemanları Toplama
org 100h jmp start vec1 db 1, 2, 5, 6 vec2 db 3, 5, 6, 1 vec3 db ?, ?, ?, ? start: lea si, vec1 lea bx, vec2 lea di, vec3 mov cx, 4 sum: mov al, [si] add al, [bx] mov [di], al inc si inc bx inc di loop sum ret
vec3[i] = vec1[i] + vec2[i], i = 0…3.JMP startveri tanımlarının üzerinden atlar; aksi hâlde işlemci veri baytlarını komut sanardı.- SI, BX, DI üç dizinin işaretçileridir;
LEAadresi (bağıl konumu) yükler. [SI]: SI'nin gösterdiği bellek baytı (dolaylı adresleme).LOOP sum: CX'i 1 azaltır, CX ≠ 0 isesum'a döner → 4 tur.- Beklenen sonuç: vec3 = 4, 7, 11, 7.
Örnek: Dizi Toplama · Kodu adım adım çalıştır
Kod İzleme: Dizi Toplama
JMP start: veriler (0102h–010Dh) atlanır, 010Eh'ye gidilir.
SI = vec1'in adresi = 0102h.
BX = 0106h (vec2), DI = 010Ah (vec3).
CX = 4 tur.
Tur 1: AL ← [SI] = [0102h] = 1.
AL ← AL + [BX] = 1 + 3 = 4 (04h).
[DI] ← AL: vec3[0] = 4.
Üç işaretçi de bir bayt ilerler (diziler bayt dizisidir; sözcük dizisi olsaydı 2 eklenirdi).
LOOP: CX = 3 ≠ 0 → sum'a dön.
Tur 2: AL ← [SI] = [0103h] = 2.
AL ← AL + [BX] = 2 + 5 = 7 (07h).
[DI] ← AL: vec3[1] = 7.
Üç işaretçi de bir bayt ilerler (diziler bayt dizisidir; sözcük dizisi olsaydı 2 eklenirdi).
LOOP: CX = 2 ≠ 0 → sum'a dön.
Tur 3 (özet): 5 + 6 = 11 → vec3[2]. LOOP: CX = 1 ≠ 0 → sum'a dön.
Tur 4 (özet): 6 + 1 = 7 → vec3[3]. LOOP: CX = 0 → döngü biter.
RET: vec3 = 4, 7, 11, 7 (04h 07h 0Bh 07h).
org 100h jmp start vec1 db 1, 2, 5, 6 vec2 db 3, 5, 6, 1 vec3 db ?, ?, ?, ? start: lea si, vec1 lea bx, vec2 lea di, vec3 mov cx, 4 sum: mov al, [si] add al, [bx] mov [di], al inc si inc bx inc di loop sum ret
Örnek: Dizi Toplama
Bellekte Program ve Veri
| Adres | Baytlar | Anlamı |
|---|---|---|
0100 | EB 0C | JMP 010Eh+0Ch: 0102h + 0Ch |
0102 | 01 02 05 06 | vec1veri |
0106 | 03 05 06 01 | vec2veri |
010A | 04 07 0B 07 | vec3çalıştıktan sonra |
010E | BE 02 01 | MOV SI, 0102hLEA → MOV |
0111 | BB 06 01 | MOV BX, 0106h |
0114 | BF 0A 01 | MOV DI, 010Ah |
| Adres | Baytlar | Anlamı |
|---|---|---|
0117 | B9 04 00 | MOV CX, 0004hlittle-endian |
011A | 8A 04 | MOV AL, [SI]sum: |
011C | 02 07 | ADD AL, [BX] |
011E | 88 05 | MOV [DI], AL |
0120 | 46 / 43 / 47 | INC SI / BX / DI1'er bayt |
0123 | E2 F5 | LOOP 011AhF5h = −11 |
0125 | C3 | RET |
emu8086 bellek penceresi (CS = DS = 0700h). Kod ve veri aynı kesimdedir; assembler LEA'yı daha kısa olan MOV reg, sabit olarak kodlamıştır.
BCD Aritmetiği
İkili Kodlu Onluk (BCD)
- BCD (Binary Coded Decimal): her onluk basamak ayrı bir 4 bitlik grupta (0000–1001) tutulur.
- Paketlenmemiş (unpacked) BCD: bayt başına bir basamak. Paketlenmiş (packed): bayt başına iki basamak.
- İşlemci toplamayı ikili yapar; sonucun BCD'ye düzeltilmesi için özel komutlar vardır.
| Gösterim | 14 sayısı | Bayt(lar) |
|---|---|---|
| İkili | 0000 1110b | 0Eh |
| Paketlenmemiş BCD | 0000 0001 · 0000 0100 | 01h 04h (AH, AL) |
| Paketlenmiş BCD | 0001 0100b | 14h |
| ASCII | '1' '4' | 31h 34h |
BCD Aritmetiği
BCD Düzeltme Komutları
| Komut | Ne zaman? | Etki |
|---|---|---|
AAA | paketlenmemiş toplamadan sonra | AL'yi BCD'ye düzelt, elde AH'ye |
AAS | paketlenmemiş çıkarmadan sonra | AL'yi düzelt, ödünç AH'den |
AAM | paketlenmemiş çarpmadan sonra | AH = AL / 10, AL = AL mod 10 |
AAD | paketlenmemiş bölmeden önce | AL = AH × 10 + AL, AH = 0 |
DAA / DAS | paketlenmiş toplama / çıkarmadan sonra | AL'deki iki basamağı düzelt |
BCD Aritmetiği · Kodu adım adım çalıştır
Kod İzleme: AAA ile 9 + 5
AH = 09h: birinci basamak 9.
AL = 05h: ikinci basamak 5. AX = 0905h.
09h + 05h = 0Eh (14): ikili doğru ama BCD değil (E > 9). Nibble eldesi yok → AF = 0.
AH = 0: onlar basamağı temizlendi. AX = 000Eh.
AAA: AL'nin düşük nibble'ı E > 9 → AL + 6 = 14h, AH + 1, AF = CF = 1; AL'nin üst nibble'ı silinir → AX = 0104h → “14”.
Her basamağa 30h eklenir: AX = 3134h = '1','4'.
BL = '4' saklanır, AL = '1'.
AH = 0Eh (teletype).
'1' yazılır.
AL = '4'.
'4' yazılır. Ekranda 14.
RET.
; first number '9': mov ah, 09h ; second number '5': mov al, 05h ; al = al + ah = 09h + 05h = 0eh add al, ah ; clear tens byte of bcd xor ah, ah ; adjust result to bcd form, ah = 1, al = 4 -> '14' aaa ; --- sonucu yazdır (ek) --- or ax, 3030h ; ASCII'ye çevir mov bl, al ; '4' sakla mov al, ah ; '1' mov ah, 0Eh int 10h mov al, bl int 10h ret
BCD Aritmetiği · Kodu adım adım çalıştır
Kod İzleme: AAS ile 5 − 8
AL = 05h. emu8086 programı AX = 0000h ile başlatır.
BL = 08h.
5 − 8 = −3 = FDh. Ödünç: CF = 1; düşük nibble'da da ödünç: AF = 1.
AAS: AF = 1 → AL − 6 = F7h, AH − 1 = FFh, CF = AF = 1; üst nibble silinir → AX = FF07h.
AL = 37h = '7'.
AH = 0Eh.
'7' yazılır.
Tuş beklenir.
Sonuç “7, ödünç 1”: 15 − 8 = 7 gibi. Gerçek fark −3'tür; CF = 1 sonucun negatif olduğunu, 7'nin −3'ün 10'a tümleyeni olduğunu söyler.
; make 5 - 8, al = 0fdh (not in bcd form) mov al, 05h mov bl, 08h sub al, bl ; convert to bcd, al = 7 ; and 1 is borrowed from ah, ; like calculating 15 - 8: aas ; --- yazdır --- or al, 30h mov ah, 0Eh int 10h mov ah, 0 int 16h ret
BCD Aritmetiği
AAM ve AAD
mov al, 7 mov bl, 8 mul bl ; AX = 0038h (56) aam ; AH = 05h, AL = 06h
AL'yi 10'a böler: bölüm AH'ye, kalan AL'ye. 56 → “5”, “6”.
mov ax, 0504h ; '54' paketlenmemiş aad ; AX = 0036h (54) mov bl, 6 div bl ; AL = 09h, AH = 00h
AL = AH × 10 + AL, AH = 0: iki basamak ikili sayıya çevrilir, sonra normal DIV.
DAA: MOV AL,38h / ADD AL,45h → AL = 7Dh, DAA → AL = 83h (38 + 45 = 83).Örnek: Sıcaklık Dönüşümü · Kodu adım adım çalıştır
Kod İzleme: °C → °F
CL = 15 (°C) = 0Fh.
AL = 9.
IMUL CL: AX = 9 × 15 = 135 = 0087h. 135 işaretli bayta sığmaz (>127) → CF = OF = 1; ama sonuç AX'te eksiksiz.
CL = 5 (bölen).
IDIV CL: AX / 5 = 135 / 5 → AL = 1Bh (27), AH = 0 (kalan). Bayraklar tanımsız.
27 + 32 = 59 = 3Bh → AX = 003Bh. 15 °C = 59 °F ✓
RET. emu8086'da son durum: AX = 003Bh, CX = 0005h.
org 100h start: ;celsius to fahrenheit according to f = c * 9 / 5 + 32 mov cl, 15 mov al, 9 imul cl mov cl, 5 idiv cl add al, 32 ret
f = c × 9 / 5 + 32. Önce çarpma, sonra bölme: 9/5 tam sayı bölmesinde 1 olurdu ve sonuç yanlış çıkardı.
Örnek: Sıcaklık Dönüşümü · Kodu adım adım çalıştır
Kod İzleme: °F → °C
CL = 59 (°F) = 3Bh.
59 − 32 = 27 = 1Bh.
AL = 5.
AX = 5 × 27 = 135 = 0087h; CF = OF = 1 (AL'ye sığmadı).
CL = 9.
135 / 9 = 15 = 0Fh → AL, kalan AH = 0. 59 °F = 15 °C ✓
RET.
org 100h start: ;fahrenheit to celsius according to: c = (f - 32) * 5 / 9 mov cl, 59 sub cl, 32 mov al, 5 imul cl mov cl, 9 idiv cl ret
Örnek: Sıcaklık Dönüşümü
Neden IMUL / IDIV? Sınırlar
c = −10: IMUL → AX = FFA6h (−90), IDIV → AL = EEh (−18), +32 → 0Eh = 14 °F ✓
MUL/DIV kullanılsaydı F6h, 246 sanılırdı ve sonuç anlamsız olurdu.
IDIV kesirli kısmı atar (sıfıra doğru): c = 1 → 9/5 = 1 → 33 °F (doğrusu 33,8). Yuvarlama için kalan (AH) incelenebilir.
Sonuç işaretli bayt AL'de: c ∈ [−71, 53]. c = 54'te AL = 81h (OF = 1, yanlış); c = 72'de bölüm AL'ye sığmaz → bölme hatası.
f − 32 bayta sığmalı: f ∈ [−96, 127]. Daha geniş aralık için sözcük işlemleri (AX, CWD, IDIV BX) kullanılır.
Özet
Özet: Hangi Komut Hangi Bayrağı Etkiler?
| Komut | CF | ZF | SF | OF | PF | AF |
|---|---|---|---|---|---|---|
ADD SUB CMP ADC SBB | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
NEG | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
INC DEC | — | ✓ | ✓ | ✓ | ✓ | ✓ |
AND OR XOR TEST | 0 | ✓ | ✓ | 0 | ✓ | ? |
NOT | — | — | — | — | — | — |
MUL IMUL | ✓ | ? | ? | ✓ | ? | ? |
DIV IDIV | ? | ? | ? | ? | ? | ? |
AAA AAS | ✓ | ? | ? | ? | ? | ✓ |
MOV LEA LOOP | — | — | — | — | — | — |
✓: sonuca göre · 0: temizlenir · —: değişmez · ?: tanımsız.
Özet
Özet
CF işaretsiz, OF işaretli taşma; ZF sıfır; SF MSB; PF düşük baytta çift sayıda 1; AF nibble eldesi.
Sonuç ilk işlenende; CMP/TEST yalnız bayrak. Mantıksal komutlar CF = OF = 0.
Örtük AL/AX/DX. Bayt: AX = AL × op, AL = AX / op (AH kalan). Sözcük: DX:AX.
INC/DEC CF'yi korur; NOT bayrak değiştirmez; NEG ikiye tümleyen.
AAA/AAS toplama/çıkarma sonrası, AAM çarpma sonrası, AAD bölme öncesi.
Bölmeden önce AH/DX hazırla; işaretli veride IMUL/IDIV; aralık taşmalarını bayraklarla denetle.
Özet
Alıştırmalar
MOV AL, 0C0h/ADD AL, 0C0hsonrası AL, CF, OF, SF, ZF, PF nedir?CMP AL, BLsonrası işaretsiz “AL < BL” hangi bayrakla, işaretli “AL < BL” hangi bayraklarla anlaşılır?- AX = 0FFFFh, BX = 0FFFFh iken
MUL BXsonrası DX, AX, CF nedir? - AX = 0100h, BL = 0 iken
DIV BLne olur? - Dizi toplama programını sözcük (DW) dizileri için değiştirin.
- Bir bayttaki 1 bitlerini sayan programı SHL/TEST ve döngüyle yazın. PF ile karşılaştırın.
İpuçları / cevaplar
- C0h + C0h = 180h → AL = 80h; CF = 1, OF = 0 (−64 + −64 = −128 sığar), SF = 1, ZF = 0, PF = 0 (tek 1 biti).
- İşaretsiz: CF = 1. İşaretli: SF ≠ OF.
- 65535² = FFFE0001h → DX = FFFEh, AX = 0001h, CF = OF = 1.
- Sıfıra bölme → bölme hatası (INT 0).
vec1 dw …,mov ax,[si],add ax,[bx],mov [di],ax; işaretçileradd si,2ile ilerler.- CX = 8 tur; her turda TEST AL,80h ile bit sınanır, 1 ise sayaç INC, sonra SHL AL,1. PF yalnızca sayının çift/tek olduğunu verir.
Özet
Kaynaklar
- Intel, The 8086 Family User's Manual, 1979 — Instruction Set bölümü.
- B. B. Brey, The Intel Microprocessors, 8. baskı, Pearson, 2009 — Bölüm 5: Aritmetik ve mantık komutları.
- emu8086 yardım belgeleri: “8086 instructions” ve “Arithmetic and logic instructions” sayfaları.
- A. S. Tanenbaum, Modern Operating Systems, 3. baskı, Pearson, 2008 (kaynak sunumda faydalanılmıştır).