Bölüm 6: Aritmetik, Mantık ve Kaydırma Komutları
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, tek işlenenli, kaydırma ve döndürme komutlarını doğru işlenenlerle kullanmak; kaydırmanın CF'ye etkisini izlemek.
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 kontrol 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… | Örnek / not |
|---|---|---|---|---|
| 0 | CF · Carry | durum | işaretsiz taşma: toplamada elde, çıkarmada ödünç | 255 + 1 → AL = 00h, CF = 1; 7 − 9 → CF = 1; STC, CLC, CMC |
| 2 | PF · Parity | durum | sonucun düşük baytında çift sayıda 1 biti var | 96h = 1001 0110b → PF = 1; sözcük sonuçta da yalnız düşük bayt |
| 4 | AF · Auxiliary | durum | bit 3'ten bit 4'e elde/ödünç | 08h + 08h → AF = 1; yalnız AAA, AAS, DAA, DAS kullanır |
| 6 | ZF · Zero | durum | sonuç sıfır | SUB AL, AL → ZF = 1; CMP AX, BX sonrası ZF = 1 ise AX = BX |
| 7 | SF · Sign | durum | sonucun en anlamlı biti (MSB) 1 | MSB'nin kopyası: 96h → SF = 1 |
| 8 | TF · Trap | kontrol | her komuttan sonra INT 1 | tek adım hata ayıklama |
| 9 | IF · Interrupt | kontrol | INTR kesmeleri kabul edilir | STI → 1, CLI → 0; NMI'yi etkilemez |
| 10 | DF · Direction | kontrol | dizgi komutları geriye doğru | 0: SI/DI artar, 1: azalır; CLD / STD |
| 11 | OF · Overflow | durum | işaretli taşma: sonuç işaretli aralığa sığmadı | 100 + 50 → AL = 96h (−106), OF = 1 |
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ı · Kodu adım adım çalıştır
Kod İzleme: CF, OF ve Diğer Bayraklar
AL = 9Ch: işaretsiz 156, işaretli −100. Bayraklar başlangıçta 0; MOV onları değiştirmez.
156 + 112 = 268 > 255 → AL = 0Ch, CF = 1. İşaretli −100 + 112 = 12 doğru → OF = 0. 0Ch'de iki tane 1 → PF = 1.
AL = 50h (80). Bayraklar önceki ADD'den kalır.
80 + 80 = 160 işaretsizde doğru (CF = 0), ama iki pozitifin toplamı negatif çıktı (A0h = −96) → OF = 1, SF = 1.
A0h + A0h: işaretsiz 320 (CF = 1), işaretli −96 + (−96) = −192 (OF = 1). AL = 40h: iki yorum da yanlış.
AL = FFh. CF = 1 hâlâ duruyor.
INC AL: FFh + 1 = 00h → ZF = 1, AF = 1; ama INC CF'ye dokunmaz: CF = 1 önceki toplamadan kaldı.
CMC CF'yi tersler: CF = 0. Diğer bayraklar değişmez.
MOV AL, 9Ch ; 156 ya da -100 ADD AL, 70h ; + 112 MOV AL, 50h ; 80 ADD AL, 50h ; + 80 ADD AL, AL ; A0h + A0h MOV AL, 0FFh INC AL ; CF'ye dokunmaz CMC ; CF tersine RET
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çilince sonuç ve bayraklar hesaplanır. Değerler onluk (-5), onaltılık (3Fh) veya ikili (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.
Grup 1: İki İşlenenli · Kodu adım adım çalıştır
SBB ile 32 Bitlik Çıkarma
Birinci sayı DX:AX = 00040000h (262144): yüksek sözcük DX, düşük sözcük AX.
Çıkarılan CX:BX = 00010001h (65537).
0000h − 0001h: düşük sözcük yetmez, ödünç alınır → AX = FFFFh, CF = 1.
SBB = SUB − CF: 0004h − 0001h − 1 = 0002h. Sonuç DX:AX = 0002FFFFh (196607) ✓
; DX:AX = 00040000h, CX:BX = 00010001h mov ax, 0000h mov dx, 0004h mov bx, 0001h mov cx, 0001h sub ax, bx ; düşük sözcükler sbb dx, cx ; yüksek - CF
Kural: en düşük sözcükte SUB, sonraki her sözcükte SBB. Aradaki komutlar CF'yi bozmamalıdır (MOV, INC, LOOP CF'yi korur).
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.
DX:AX = FFFFFFFFh, DIV BX (BX = 1): bölen sıfır değil, ama bölüm FFFFFFFFh AX'e sığmaz → yine INT 0. Kural: sözcük bölmede DX ≥ bölen ise bölüm sığmaz (bayt bölmede AH ≥ bölen).
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 · Kodu adım adım çalıştır
Kod İzleme: DIV, CWD ve IDIV
AX = 2000 = 07D0h. Sözcük bölmede bölünen DX:AX'tir; DX'te ne olduğu da önemlidir.
XOR DX, DX: işaretsiz bölme için üst yarı sıfır → DX:AX = 2000.
Bölen BX = 9.
DIV BX: 2000 / 9 → AX = 222 (00DEh), DX = 2. Bayraklar tanımsız.
AX = −2000 = F830h. DX'te önceki kalan (2) duruyor: DX:AX şimdi yanlış bir bölünen.
CWD: AX'in işaret biti 1 → DX = FFFFh. DX:AX = FFFFF830h, 32 bitte −2000.
IDIV BX: −2000 / 9 → AX = FF22h (−222), DX = FFFEh (−2). Kalan bölünenle aynı işaretli.
AX = 2000, ama DX = FFFEh temizlenmedi: DX:AX = FFFE07D0h, yaklaşık 4,29 milyar.
DIV BX: bölüm 16 bite sığmaz (DX ≥ bölen) → işlemci INT 0 üretir, program durur. Çözüm: bölmeden önce XOR DX, DX.
MOV AX, 2000 XOR DX, DX ; DX:AX = 2000 MOV BX, 9 DIV BX ; işaretsiz bölme MOV AX, -2000 CWD ; işaret genişlet IDIV BX ; işaretli bölme MOV AX, 2000 ; DX temizlenmedi! DIV BX RET
İşaretli Sayılar · Kodu adım adım çalıştır
İşaretli Taşma: JO ve CBW
AL = BL = A4h: −92 (256 − 92 = 164 = A4h).
A4h + A4h = 148h → AL = 48h = +72. İki negatifin toplamı pozitif çıktı → OF = 1 (CF = 1 de oldu ama işaretli yorumda önemsiz).
JO OF = 1 olduğu için genislet etiketine atlar. Doğru sonuç −184, −128 … 127 aralığında değil.
AL = A4h, CBW: MSB = 1 → AH = FFh, AX = FFA4h (16 bitte −92).
Birinci sayı DX'e saklanır; ikinci sayı (BL) da AL'ye alınıp genişletilir: AX = FFA4h.
FFA4h + FFA4h = 1FF48h → AX = FF48h = −184 ✓. Sonuç 16 bite sığdı: OF = 0.
mov al, -92 ; A4h mov bl, -92 add al, bl ; 8 bit toplama jo genislet ; OF = 1 ise jmp bitti genislet: mov al, -92 ; birinci sayı cbw ; AL -> AX mov dx, ax mov al, bl ; ikinci sayı cbw add ax, dx ; 16 bit toplama bitti: ret
JO (jump if overflow) OF = 1 ise, JNO OF = 0 ise atlar. İşaretli bayt toplamı taşabiliyorsa işlenenler önce CBW ile sözcüğe genişletilir.
İşaretli Sayılar · Kodu adım adım çalıştır
CBW ile İşaretli Bayt Toplamı
SI dizinin başını gösterir, CX = 4 eleman, BX = 0 (toplam sıfırlandı).
AL = 64h (+100). MSB = 0 → CBW AH = 00h, AX = 0064h.
BX = BX + AX = 0064h (100).
AL = E2h (−30). MSB = 1 → CBW AH = FFh, AX = FFE2h.
BX = BX + AX = 0046h (70).
AL = 5Ah (+90). MSB = 0 → CBW AH = 00h, AX = 005Ah.
BX = 00A0h (160). Bayt toplasaydık 70 + 90 = 160 > 127 → AL = A0h (−96), OF = 1 olurdu.
AL = F9h (−7). MSB = 1 → CBW AH = FFh, AX = FFF9h.
BX = BX + AX = 0099h (153).
Döngü bitti, toplam = 0099h = 153 ✓ belleğe yazılır. CBW yerine MOV AH, 0 kullanılsaydı −30 = E2h, 226 olarak eklenirdi.
org 100h jmp basla dizi db 100, -30, 90, -7 toplam dw 0 basla: lea si, dizi mov cx, 4 xor bx, bx ; BX = 16 bit toplam dongu: mov al, [si] cbw ; AL -> AX (işaretle) add bx, ax inc si loop dongu mov toplam, bx ; 153 = 0099h ret
İşaretli Sayılar · Kodu adım adım çalıştır
CWD ve ADC ile 32 Bitlik Toplam
SI = dizi, CX = 3 sözcük. Toplam (32 bit) bellekte 0000:0000.
AX = 7530h (30000). Pozitif → CWD DX = 0000h.
Düşük sözcük: 0000h + 7530h = 7530h, CF = 0.
Yüksek sözcük: 0000h + 0000h + CF(0) = 0000h. Toplam 00007530h.
AX = 61A8h (25000), DX = 0000h.
7530h + 61A8h = D6D8h (55000). 16 bit işaretli yorumda negatif (OF = 1) ama toplam 32 bit tutulduğu için sorun yok.
Yüksek sözcük 0000h kalır: toplam 0000D6D8h = 55000.
AX = F060h (−4000). MSB = 1 → CWD DX = FFFFh: DX:AX = FFFFF060h (32 bitte −4000).
D6D8h + F060h = 1C738h → düşük sözcük C738h, CF = 1.
FFFFh + 0000h + CF(1) = 10000h → yüksek sözcük 0000h. Toplam 0000C738h = 51000 ✓
org 100h jmp basla dizi dw 30000, 25000, -4000 toplam dw 0, 0 ; 32 bit toplam basla: lea si, dizi mov cx, 3 dongu: mov ax, [si] cwd ; AX -> DX:AX add [toplam], ax ; düşük sözcük adc [toplam+2], dx ; yüksek + CF add si, 2 loop dongu ret
İşaretli sözcük dizisi: her eleman CWD ile 32 bite genişletilir, düşük sözcük ADD, yüksek sözcük ADC ile toplanır.
Grup 2: Çarpma ve Bölme
Demo: Çarpma / Bölme Hesaplayıcı
Komut, boyut ve değerler seçilince sonucun hangi yazmaçlara yazıldığı gösterilir. Bölmede bölünen, bayt için AX; sözcük için DX:AX'tir.
Grup 2: Çarpma ve Bölme · Adım adım
32 × 32 Bit Çarpma: Kısmi Çarpımlar
8086 en çok 16 × 16 bit çarpar. 32 bitlik sayılar sözcüklere bölünür: A × B = A1·B1·232 + (A1·B0 + A0·B1)·216 + A0·B0. Dört MUL, sonuçlar sözcük konumuna göre ADD/ADC ile toplanır; sonuç 64 bittir.
A = 9ABCDEF0h ve B = EDCBFEDCh, 16 bitlik yarılara ayrılır: A = A1:A0, B = B1:B0.
A0 × B0 kaydırılmaz: sonucun en düşük iki sözcüğüne (z1:z0) düşer.
A1 × B0 ve A0 × B1 ikisi de 216 ile çarpılmıştır: z2:z1 sütunlarına yazılır.
A1 × B1 232 ile çarpılmıştır: z3:z2 sütunlarına yazılır.
Sütun toplamları: z1 = 257D1h → yaz 57D1h, 2 elde; z2 = 22835h → yaz 2835h, 2 elde. Her ADD en çok 1 elde verir: kodda ADC zinciri bu yüzden var.
Sonuç: 8FBC 2835 57D1 B640h. Kontrol (onluk): 2596069104 × 3989569244 = 10357197452617037376 ✓
Grup 2: Çarpma ve Bölme · Kodu adım adım çalıştır
32 × 32 Bit Çarpma: Kod İzleme
AX = A0 = DEF0h, MUL [y]: A0 × B0 = DEF0h × FEDCh = DDF1:B640h (DX:AX). DX ≠ 0 olduğundan MUL CF = 1 yapar.
İlk kısmi çarpım z0 (bit 0–15) ve z1 (bit 16–31) sözcüklerine yazılır.
A1 × B0 = 9ABCh × FEDCh = 9A0B:8190h. 16 bit sola kaymış: z1 ve z2'ye eklenecek.
z1 + AX = DDF1h + 8190h → z1 = 5F81h, CF = 1.
z2 = 0 + DX + CF = 9A0Ch. z2 önceden 0 olduğu için burada yeni elde oluşmaz.
A0 × B1 = DEF0h × EDCBh = CF14:F850h. Bu da z1–z2 konumuna eklenir.
z1 = 5F81h + F850h → 57D1h, CF = 1.
z2 = 9A0Ch + CF14h + CF → 6921h, CF = 1: elde z3'e gitmeli!
ADC [z+6], 0: yalnızca eldeyi taşır → z3 = 0001h.
A1 × B1 = 9ABCh × EDCBh = 8FBA:BF14h, 32 bit sola kaymış: z2–z3.
z2 = 6921h + BF14h → 2835h, CF = 1.
z3 = 0001h + 8FBAh + CF = 8FBCh. Sonuç z3:z2:z1:z0 = 8FBC 2835 57D1 B640h ✓
org 100h mov ax, [x] ; A0 mul [y] ; A0*B0 mov [z], ax mov [z+2], dx mov ax, [x+2] ; A1 mul [y] ; A1*B0 add [z+2], ax adc [z+4], dx mov ax, [x] ; A0 mul [y+2] ; A0*B1 add [z+2], ax adc [z+4], dx adc [z+6], 0 mov ax, [x+2] ; A1 mul [y+2] ; A1*B1 add [z+4], ax adc [z+6], dx ret x dw 0DEF0h, 9ABCh ; A = 9ABCDEF0h y dw 0FEDCh, 0EDCBh ; B = EDCBFEDCh z dw 4 dup(0) ; 64 bit sonuç
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 (birler tümleyeni).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). Birler tümleyeni.
+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
Kaydırma ve Döndürme
Kaydırma: SHL/SAL, SHR, SAR
SHL/SAL: sola kaydır, sağdan 0 girer, çıkan bit CF'ye. Her adım × 2.SHR: mantıksal sağa kaydır, soldan 0 girer. İşaretsiz ÷ 2.SAR: aritmetik sağa kaydır, işaret biti korunur. İşaretli ÷ 2 (−∞'a yuvarlar).1 ya da CL: shl ax, 1, shr al, cl. shl al, 4 gibi anlık sayı 80186 ve sonrasında geçerlidir. OF yalnızca sayı 1 iken tanımlıdır.sar 1 → FCh = −4; idiv 2 → −3.Kaydırma ve Döndürme
Döndürme: ROL, ROR, RCL, RCR
ROL: sola döndür; b7 hem b0'a hem CF'ye gider.ROR: sağa döndür; b0 hem b7'ye hem CF'ye gider.RCL: CF üzerinden sola döndür (9 bitlik halka).RCR: CF üzerinden sağa döndür.shl ax, 1 + rcl dx, 1 → DX:AX × 2.Kaydırma ve Döndürme
Kaydırma ve Döndürme Gezgini
Her düğme komutu op al, 1 olarak uygular. SHL art arda seçilince sayı her adımda iki katına çıkar; SAR işaret bitini korur.
Kaydırma ve Döndürme · Kodu adım adım çalıştır
Kod İzleme: Kaydırarak Çarpma (13 × 5)
Çarpılan BL = 13 = 0Dh (0000 1101b).
Çarpan DL = 5 = 0101b: kâğıt üzerindeki çarpmada olduğu gibi bitler tek tek incelenir.
4 bitlik çarpan için 4 tur.
shr dl, 1: çıkan bit 1 → CF = 1.
CF = 1 → atlama yok, toplama yapılacak.
sonuc = 0 + 0Dh = 0Dh (13 × 1).
Çarpılan bir sola: BL = 1Ah (26).
loop: CX = 0003h.
Çıkan bit 0 → CF = 0.
CF = 0 → atla'ya atlar.
BL = 34h (52).
loop: CX = 0002h.
Çıkan bit 1 → CF = 1.
CF = 1 → toplama yapılacak.
sonuc = 0Dh + 34h = 41h = 65 (13 × 4 eklendi).
BL = 68h (104).
loop: CX = 0001h.
Çıkan bit 0 → CF = 0.
CF = 0 → atla.
BL = D0h.
loop: CX = 0000h.
Sonuç: 13 × 5 = 65 = 41h. MUL olmayan işlemcilerde çarpma böyle yapılır.
org 100h mov bl, carpilan ; 13 mov dl, carpan ; 5 = 0101b mov cx, 4 ; 4 bit kontrol: shr dl, 1 ; en sağ bit → CF jnc atla add sonuc, bl ; bit 1 ise ekle atla: shl bl, 1 ; çarpılan × 2 loop kontrol ret carpilan db 13 carpan db 5 sonuc db 0
Kaydırma ve Döndürme
Kaydırmayla Hızlı Çarpma ve Bölme
; AX ← AX × 3 = AX×2 + AX mov bx, ax ; sakla shl ax, 1 ; AX × 2 add ax, bx ; ×2 + ×1 ; işaretsiz ÷ 8 ve kalan mov dx, ax and dx, 0007h ; kalan = alt 3 bit mov cl, 3 shr ax, cl ; bölüm ; işaretli ÷ 4 mov cl, 2 sar ax, cl ; −7 → −2
- 8086'da
mul70–133,div80–162 saat turu sürer; birshl reg, 1yalnızca 2 tur. - 2'nin kuvvetleriyle çarpma/bölme kaydırmaya, diğer sabitler kaydırma + toplamaya dönüştürülebilir.
- 2n'e bölümden kalan:
andile alt n bit. - İşaretli bölmede SAR kullanılır; negatif bölünende SAR −∞'a, IDIV sıfıra doğru yuvarlar: −7 için SAR 2 → −2, IDIV 4 → −1.
Kaydırma ve Döndürme · Kodu adım adım çalıştır
Kaydırmayla 37 × 10 ve 370 ÷ 16
org 100h mov ax, 37 shl ax, 1 ; AX × 2 mov bx, ax ; sakla shl ax, 1 ; AX × 4 shl ax, 1 ; AX × 8 add ax, bx ; ×8 + ×2 mov bx, ax and bx, 000Fh ; kalan: alt 4 bit mov cl, 4 shr ax, cl ; bölüm: ÷ 16 ret
AX = 37 = 0025h = 0000 0000 0010 0101b.
SHL AX, 1: bitler bir sola, sağdan 0 girer → AX = 74 (004Ah). 2 saat turu; MUL 70 turdan fazla sürer.
BX = 74: ×2 saklanır.
SHL → AX = 148 (×4).
SHL → AX = 296 (×8).
ADD AX, BX: 296 + 74 = 370 = 0172h = 37 × 10.
BX = 370: bölme için kopya.
AND BX, 000Fh: alt 4 bit = 370 mod 16 = 2.
CL = 4: 8086'da 1'den büyük kaydırma sayısı CL ile verilir.
SHR AX, CL: 4 bit sağa = ÷ 16 → AX = 23 (0017h). 23 × 16 + 2 = 370.
RET: program biter.
Ö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.
- Paketsiz (unpacked) BCD: bayt başına bir basamak. Paketli (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 |
| Paketsiz BCD | 0000 0001 · 0000 0100 | 01h 04h (AH, AL) |
| Paketli BCD | 0001 0100b | 14h |
| ASCII | '1' '4' | 31h 34h |
BCD Aritmetiği
BCD Düzeltme Komutları
| Komut | Ne zaman? | Etki |
|---|---|---|
AAA | paketsiz toplamadan sonra | AL'yi BCD'ye düzelt, elde AH'ye |
AAS | paketsiz çıkarmadan sonra | AL'yi düzelt, ödünç AH'den |
AAM | paketsiz çarpmadan sonra | AH = AL / 10, AL = AL mod 10 |
AAD | paketsiz bölmeden önce | AL = AH × 10 + AL, AH = 0 |
DAA / DAS | paketli toplama / çıkarmadan sonra | AL'deki iki basamağı düzelt |
DAS → 45h (83 − 38 = 45).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' paketsiz 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).BCD Aritmetiği · Kodu adım adım çalıştır
Kod İzleme: AAM, AAD ve DAA
İki tek basamaklı sayı: AL = 6, BL = 9.
MUL BL: AX = 6 × 9 = 54 = 0036h. İkili sonuç; ekrana yazmak için basamaklara ayrılmalı.
AAM: AL / 10 → AH = 5 (bölüm), AL = 4 (kalan). AX = 0504h: paketsiz “54”.
AX = 0702h: paketsiz BCD “72” (AH = 7, AL = 2).
AAD: AL = 7 × 10 + 2 = 72 = 48h, AH = 0. Bölmeden önce ikiliye çevrildi.
DIV BL: 72 / 8 → AL = 9, AH = 0 (kalan). AAD olmasaydı 0702h = 1794 bölünürdü.
AL = 19h: paketli BCD “19” (bir baytta iki basamak).
19h + 28h = 41h: ikili toplama. 9 + 8 = 17 alt nibble'dan taştı → AF = 1; 41h BCD olarak yanlış.
DAA: AF = 1 → AL + 06h = 47h. Sonuç “47” = 19 + 28 ✓
MOV AL, 6 MOV BL, 9 MUL BL ; AX = 6 × 9 AAM ; basamaklara ayır MOV AX, 0702h ; '72' paketsiz AAD ; ikiliye çevir MOV BL, 8 DIV BL MOV AL, 19h ; paketli 19 ADD AL, 28h ; + 28 DAA ; BCD düzelt RET
Ö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.
Laboratuvar · 8086 komutları adım adım
Laboratuvar: Aritmetik ve Mantık
Ö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 | ? | ? | ? | ? | ? | ? |
SHL SHR SAR | ✓ | ✓ | ✓ | ✓¹ | ✓ | ? |
ROL ROR RCL RCR | ✓ | — | — | ✓¹ | — | — |
AAA AAS | ✓ | ? | ? | ? | ? | ✓ |
MOV LEA LOOP | — | — | — | — | — | — |
✓: sonuca göre · 0: temizlenir · —: değişmez · ?: tanımsız · ¹: yalnız kaydırma sayısı 1 iken tanımlı.
Ö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.
Sayı 1 ya da CL. SHL ×2, SHR işaretsiz ÷2, SAR işaretli ÷2 (−∞'a yuvarlar); döndürmede bit kaybolmaz, RCL/RCR CF ile 9 (17) bitlik halka kurar.
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
Alıştırmalar (2)
- DX = 0005h, AX = 0000h, BX = 0005h iken
DIV BXne olur? MOV AL, 70h/ADD AL, 30hsonrası AL ve OF nedir? Doğru toplamı 16 bitte nasıl elde edersiniz?- 00012345h − 0000ABCDh işlemini SUB/SBB ile yapın. SUB sonrası CF kaçtır?
- 32 × 32 bit çarpmada dört kısmi çarpım sonucun hangi sözcüklerine eklenir?
- DX = 0000h, AX = 0FFFh, CF = 0 iken
SHL AX, 1veRCL DX, 1sonrası DX:AX nedir?
İpuçları / cevaplar
- DX ≥ BX: bölüm 50000h = 327680 AX'e sığmaz → bölme hatası (INT 0), bölen sıfır olmasa da.
- AL = A0h, OF = 1 (112 + 48 = 160 > 127). İki sayı ayrı ayrı
CBWile genişletilip 16 bitte toplanır: 00A0h = 160. - 2345h − ABCDh = 7778h, CF = 1 (ödünç); 0001h − 0000h − 1 = 0000h → 00007778h (30584).
- A0·B0 → z1:z0; A1·B0 ve A0·B1 → z2:z1; A1·B1 → z3:z2. Eldeler ADC ile bir üst sözcüğe taşınır.
- AX = 1FFEh, çıkan bit 0 → CF = 0; RCL DX'e 0 sokar → DX = 0000h. DX:AX = 00001FFEh (0FFFh × 2).
Ö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, mantık, kaydırma ve döndürme komutları.
- emu8086 yardım belgeleri: “8086 instructions” ve “Arithmetic and logic instructions” sayfaları.
- K. R. Irvine, Assembly Language for x86 Processors, 7. baskı, Pearson, 2014 — Bölüm 7: Kaydırma ve döndürme komutları.
- A. S. Tanenbaum, Modern Operating Systems, 3. baskı, Pearson, 2008.
- M. Bodur, Mikroişlemcilere Giriş: Assembler ile Yazılım ve Arayüz, EMO, 2014.
- Ş. Ç. Öztürk, O. Ergin, Intel 8086 ile Mikroişlemci Programlamaya Giriş, 2009.