Bölüm 6: Aritmetik ve Mantıksal İşlemler

Mikroişlemciler
Bayrak yazmacıCF · ZF · SF · OF · PF · AFKomut gruplarıADD · SUB · CMPAND · OR · XOR · TESTMUL · IMUL · DIV · IDIVINC · DEC · NOT · NEGDizi toplamaBCD: AAA · AASSıcaklık dönüşümü
Sercan KÜLCÜ · Giresun Üniversitesi · Elektrik-Elektronik Mühendisliği

Giriş

Öğrenme Çıktıları

Bayraklar

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.

Komutlar

Toplama, çıkarma, karşılaştırma, mantıksal, çarpma, bölme ve tek işlenenli komutları doğru işlenenlerle kullanmak.

Çarpma / bölme

MUL, IMUL, DIV, IDIV'in örtük yazmaçlarını (AL, AX, DX:AX) ve bölme hatasını bilmek.

Uygulama

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.
1514131211OF10DF9IF8TF7SF6ZF54AF32PF10CFdenetim bayrakları: DF, IF, TFdurum bayrakları: OF, SF, ZF, AF, PF, CF

Kesik çizgili bitler 8086'da kullanılmaz.

Bayrak Yazmacı

Bayraklar Tablosu

BitBayrakTür1 olur, eğer…
0CF · Carrydurumişaretsiz taşma: toplamada elde, çıkarmada ödünç oluştu
2PF · Paritydurumsonucun düşük baytında çift sayıda 1 biti var
4AF · Auxiliarydurumbit 3'ten bit 4'e elde/ödünç oluştu (BCD için)
6ZF · Zerodurumsonuç sıfır
7SF · Signdurumsonucun en anlamlı biti (MSB) 1
8TF · Trapdenetimher komuttan sonra INT 1 (tek adım hata ayıklama)
9IF · InterruptdenetimINTR kesmeleri kabul edilir (STI / CLI)
10DF · Directiondenetimdizgi komutları geriye doğru (STD / CLD)
11OF · Overflowdurumişaretli taşma: sonuç işaretli aralığa sığmadı

Bayrak Yazmacı

CF ve ZF

Taşıma bayrağı · CF (Carry)
  • İş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, CMC ile doğrudan değiştirilebilir.
Sıfır bayrağı · ZF (Zero)
  • Sonuç sıfır ise 1 olur.
  • Sıfır olmayan sonuçta 0.
  • Ör. SUB AL, AL → ZF = 1.
  • CMP AX, BX sonrası 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

SF (Sign)

Sonuç negatif ise 1, pozitif veya sıfır ise 0. Aslında sonucun en anlamlı bitinin (MSB) kopyasıdır.

OF (Overflow)

İşaretli bir taşma olduğunda 1. Ör. 100 + 50 = 150; sonuç −128…127 aralığında değil → AL = 96h (−106), OF = 1.

PF (Parity)

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.

Kaynak sunumda PF tersine yazılmıştı. Doğrusu: 1 bitlerinin sayısı çift → PF = 1, tek → PF = 0. Örnek: 96h = 1001 0110b, dört tane 1 → PF = 1.
MOV AL, 100
ADD AL, 50    ; AL = 96h: SF = 1, OF = 1, CF = 0, PF = 1

Bayrak Yazmacı

AF, IF, DF ve TF

AF (Auxiliary carry)

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.

IF (Interrupt enable)

1 iken CPU, harici aygıtlardan gelen (INTR) kesmelere tepki verir. STI → 1, CLI → 0. NMI'yi etkilemez.

DF (Direction)

Dizgi (string) komutları bu bayrağı kullanır: 0 iken SI/DI artar (ileri), 1 iken azalır (geri). CLD / STD.

TF (Trap)

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şlenenişaretsiz yorumişaretli yorumALCFOF
FFh + 01h255 + 1 = 256-1 + 1 = 000h10
64h + 32h100 + 50 = 150100 + 50 = 15096h01
C8h + 64h200 + 100 = 300-56 + 100 = 442Ch10
80h + 80h128 + 128 = 256-128 + -128 = -25600h11
05h + 0Ah5 + 10 = 155 + 10 = 150Fh00
OF kuralı: aynı işaretli iki sayının toplamı farklı işaretli çıkarsa OF = 1. Farklı işaretli iki sayı toplanınca OF hiçbir zaman 1 olmaz.

Bayrak Yazmacı

ADD ile Bayraklar Adım Adım

A = 64h0716150403120100B = 32h00110010

MOV AL, 64h (100) ve ADD AL, 32h (50). Bitler sağdan sola toplanır.

A = 64h0716150403120100B = 32h00110010AL = 96h10010110

Sonuç 96h = 1001 0110b. İşaretsiz yorumla 150 (doğru), işaretli yorumla −106 (yanlış!).

A = 64h0716150403120100B = 32h00110010AL = 96h10010110bit 7'den dışarı elde: 0→ CF = 0

CF: en soldaki bitten dışarı elde çıktı mı? Hayır → CF = 0 (150 ≤ 255).

A = 64h0716150403120100B = 32h00110010AL = 96h10010110bit 7'ye giren elde 1, çıkan 0→ OF = 1

OF: iki pozitif sayının toplamı negatif çıktı (bit 7'ye giren ve çıkan elde farklı) → OF = 1.

A = 64h0716150403120100B = 32h00110010AL = 96h10010110MSB = 1 → SF = 1sonuç ≠ 0 → ZF = 0

SF = sonucun bit 7'si = 1. Sonuç sıfır değil: ZF = 0.

A = 64h0716150403120100B = 32h00110010AL = 96h10010110dört tane 1 (çift) → PF = 14 + 2 nibble: elde yok → AF = 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

1. grup · iki işlenenli

ADD, SUB, CMP, AND, TEST, OR, XOR

hedef, kaynak

2. grup · çarpma ve bölme

MUL, IMUL, DIV, IDIV

tek işlenen + örtük AL / AX / DX

3. grup · tek işlenenli

INC, DEC, NOT, NEG

işlenen hem kaynak hem hedef

Kaynak sunumda birinci grup “Artırma ve Azaltma” olarak adlandırılmıştı; artırma (INC) ve azaltma (DEC) aslında üçüncü gruptadır. Gruplar, işlenen biçimine göre ayrılır.

Komut Grupları

Komutların Anlamı

1. grupNe yapar?
ADDiki değeri toplar, sonucu hedefe yazar
SUBkaynağı hedeften çıkarır, sonucu hedefe yazar
CMPçıkarır ama sonucu saklamaz; yalnız bayraklar
ANDbit düzeyinde VE
TESTbit düzeyinde VE; sonucu saklamaz
ORbit düzeyinde VEYA
XORbit düzeyinde dışlayan VEYA
2. grupNe yapar?
MULişaretsiz çarpma
IMULişaretli çarpma
DIVişaretsiz bölme (bölüm + kalan)
IDIVişaretli bölme
3. grupNe yapar?
INC1 artırır
DEC1 azaltır
NOTtüm bitleri tersler
NEGişaretini değiştirir (ikiye tümleyen)

Grup 1: İki İşlenenli

ADD, SUB, CMP, AND, TEST, OR, XOR: İşlenenler

BiçimÖrnek
REG, memoryADD AX, [BX]
memory, REGSUB var1, CL
REG, REGXOR AX, AX
memory, immediateAND byte ptr [SI], 0Fh
REG, immediateCMP 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 …
Geçersiz: 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.
  • CMP ve TEST yalnı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.
KomutCFZFSFOFPFAF
ADD, SUB, CMP✓✓✓✓✓✓
AND, OR, XOR, TEST0✓✓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ı

AND (VE)
ABA AND B
111
100
010
000

İkisi de 1 ise 1.

OR (VEYA)
ABA OR B
111
101
011
000

En az biri 1 ise 1.

XOR (dışlayan)
ABA XOR B
110
101
011
000

Farklı ise 1.

NOT (değil)
ANOT A
10
01

Tersler. Tek işlenenli.

Bu kurallar 8 ya da 16 bitin her birine ayrı ayrı uygulanır: AND AL, BL aslında 8 tane bağımsız VE işlemidir.

Mantıksal İşlemler

Maskeleme: AND, OR, XOR, TEST

AL='a' 61h0716150403020110maske DFh11011111ANDAL='A' 41h01000001

AND ile bit temizleme: maskede 0 olan bit 5 sıfırlanır, diğerleri korunur → küçük harf büyük olur.

AL='A' 41h0716050403020110maske 20h00100000ORAL='a' 61h01100001

OR ile bit kurma: maskede 1 olan bit 5 kesin 1 olur → büyük harf küçük olur.

AL='a' 61h0716150403020110maske 20h00100000XORAL='A' 41h01000001

XOR ile bit tersleme: maskede 1 olan bit değişir → harfin büyük/küçük hâli yer değiştirir.

BL='7' 37h0706151403121110maske 01h00000001TEST(saklanmaz)00000001

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

KodEtkiNeden?
XOR AX, AXAX = 0, ZF = 1, CF = 0MOV AX, 0'dan kısa (2 bayt); bayrakları da temizler
AND AL, 0Fh'7' (37h) → 7ASCII rakamı sayıya çevirir (yüksek nibble silinir)
OR AL, 30h7 → '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, 1ZF = 0 ise tekAL değişmeden bit 0 sınanır
TEST AL, 80hZF = 0 ise negatifişaret biti sınanır
OR AX, AXAX değişmezZF/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

bayt işlenen (8 bit)AL×işlenenAX (16 bit)MUL / IMULsözcük işlenen (16 bit)AX×işlenenDXAX32 bitlik sonuç DX:AX (DX yüksek)
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
Bayraklar

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ölme hatası

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

ALC8hBL03h

MOV AL, 200, MOV BL, 3. 200 = C8h, işaretli yorumda −56.

AX0258hCF1OF1

MUL BL: 200 × 3 = 600 = 0258h → AX. Sonuç AL'ye sığmadı (AH ≠ 0) → CF = OF = 1.

AXFF58hCF1OF1

Aynı bitlerle IMUL BL: −56 × 3 = −168 = FF58h. Farklı sonuç! −168 bayta sığmaz → CF = OF = 1.

AXFFF6hCF0OF0

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ı.

AX0017hBL05hAL04hAH03h

DIV BL: AX = 23, BL = 5 → bölüm AL = 4, kalan AH = 3. Yeni AX = 0304h.

AXFFE9hBL05hALFChAHFDh

IDIV BL: −23 / 5 → bölüm AL = FCh (−4), kalan AH = FDh (−3). Kontrol: −4 × 5 + (−3) = −23.

AX1000hBL02hAL?

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, 0 veya XOR 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.
  • INC ve DEC yalnızca ZF, SF, OF, PF, AF'yi etkiler; CF'ye dokunmaz.
  • NOT hiçbir bayrağı etkilemez! İşlenenin her bitini ters çevirir (bire tümleyen).
  • NEG CF, 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.
KomutCFZFSFOFPFAF
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 = 05h0706050403120110

x = 5 = 0000 0101b.

x = 05h0706050403120110NOT x11111010FAh

NOT: her bit terslenir → 1111 1010b = FAh (−6). Bire tümleyen.

x = 05h0706050403120110NOT x11111010FAh+ 1 → NEG11111011FBh

+1: FBh = 1111 1011b = −5. NEG bu iki adımı tek komutta yapar; CF = 1 (x ≠ 0).

x = FEh1716151413121100NOT x0000000101h+ 1 → NEG0000001002h

x = FEh (−2): NOT → 01h, +1 → 02h. Negatifin negatifi pozitiftir.

x = 80h1706050403020100NOT x011111117Fh+ 1 → NEG1000000080h

Özel durum: x = 80h (−128). NOT → 7Fh, +1 → 80h: +128 bayta sığmaz → OF = 1.

x = 00h0706050403020100NOT x11111111FFh+ 1 → NEG0000000000h

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 start veri tanımlarının üzerinden atlar; aksi hâlde işlemci veri baytlarını komut sanardı.
  • SI, BX, DI üç dizinin işaretçileridir; LEA adresi (bağıl konumu) yükler.
  • [SI]: SI'nin gösterdiği bellek baytı (dolaylı adresleme).
  • LOOP sum: CX'i 1 azaltır, CX ≠ 0 ise sum'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

vec1 (0102h)1256vec2 (0106h)3561vec3 (010Ah)0000

JMP start: veriler (0102h–010Dh) atlanır, 010Eh'ye gidilir.

vec1 (0102h)1256▲SIvec2 (0106h)3561vec3 (010Ah)0000

SI = vec1'in adresi = 0102h.

vec1 (0102h)1256▲SIvec2 (0106h)3561▲BXvec3 (010Ah)0000▲DI

BX = 0106h (vec2), DI = 010Ah (vec3).

vec1 (0102h)1256▲SIvec2 (0106h)3561▲BXvec3 (010Ah)0000▲DI

CX = 4 tur.

vec1 (0102h)1256▲SIvec2 (0106h)3561▲BXvec3 (010Ah)0000▲DI

Tur 1: AL ← [SI] = [0102h] = 1.

vec1 (0102h)1256▲SIvec2 (0106h)3561▲BXvec3 (010Ah)0000▲DI

AL ← AL + [BX] = 1 + 3 = 4 (04h).

vec1 (0102h)1256▲SIvec2 (0106h)3561▲BXvec3 (010Ah)4000▲DI

[DI] ← AL: vec3[0] = 4.

vec1 (0102h)1256▲SIvec2 (0106h)3561▲BXvec3 (010Ah)4000▲DI

Üç işaretçi de bir bayt ilerler (diziler bayt dizisidir; sözcük dizisi olsaydı 2 eklenirdi).

vec1 (0102h)1256▲SIvec2 (0106h)3561▲BXvec3 (010Ah)4000▲DI

LOOP: CX = 3 ≠ 0 → sum'a dön.

vec1 (0102h)1256▲SIvec2 (0106h)3561▲BXvec3 (010Ah)4000▲DI

Tur 2: AL ← [SI] = [0103h] = 2.

vec1 (0102h)1256▲SIvec2 (0106h)3561▲BXvec3 (010Ah)4000▲DI

AL ← AL + [BX] = 2 + 5 = 7 (07h).

vec1 (0102h)1256▲SIvec2 (0106h)3561▲BXvec3 (010Ah)4700▲DI

[DI] ← AL: vec3[1] = 7.

vec1 (0102h)1256▲SIvec2 (0106h)3561▲BXvec3 (010Ah)4700▲DI

Üç işaretçi de bir bayt ilerler (diziler bayt dizisidir; sözcük dizisi olsaydı 2 eklenirdi).

vec1 (0102h)1256▲SIvec2 (0106h)3561▲BXvec3 (010Ah)4700▲DI

LOOP: CX = 2 ≠ 0 → sum'a dön.

vec1 (0102h)1256▲SIvec2 (0106h)3561▲BXvec3 (010Ah)47110▲DI

Tur 3 (özet): 5 + 6 = 11 → vec3[2]. LOOP: CX = 1 ≠ 0 → sum'a dön.

vec1 (0102h)1256vec2 (0106h)3561▲SIvec3 (010Ah)47117▲BX

Tur 4 (özet): 6 + 1 = 7 → vec3[3]. LOOP: CX = 0 → döngü biter.

vec1 (0102h)1256vec2 (0106h)3561▲SIvec3 (010Ah)47117▲BX

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

AdresBaytlarAnlamı
0100EB 0CJMP 010Eh
+0Ch: 0102h + 0Ch
010201 02 05 06vec1
veri
010603 05 06 01vec2
veri
010A04 07 0B 07vec3
çalıştıktan sonra
010EBE 02 01MOV SI, 0102h
LEA → MOV
0111BB 06 01MOV BX, 0106h
0114BF 0A 01MOV DI, 010Ah
AdresBaytlarAnlamı
0117B9 04 00MOV CX, 0004h
little-endian
011A8A 04MOV AL, [SI]
sum:
011C02 07ADD AL, [BX]
011E88 05MOV [DI], AL
012046 / 43 / 47INC SI / BX / DI
1'er bayt
0123E2 F5LOOP 011Ah
F5h = −11
0125C3RET

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österim14 sayısıBayt(lar)
İkili0000 1110b0Eh
Paketlenmemiş BCD0000 0001 · 0000 010001h 04h (AH, AL)
Paketlenmiş BCD0001 0100b14h
ASCII'1' '4'31h 34h

BCD Aritmetiği

BCD Düzeltme Komutları

KomutNe zaman?Etki
AAApaketlenmemiş toplamadan sonraAL'yi BCD'ye düzelt, elde AH'ye
AASpaketlenmemiş çıkarmadan sonraAL'yi düzelt, ödünç AH'den
AAMpaketlenmemiş çarpmadan sonraAH = AL / 10, AL = AL mod 10
AADpaketlenmemiş bölmeden önceAL = AH × 10 + AL, AH = 0
DAA / DASpaketlenmiş toplama / çıkarmadan sonraAL'deki iki basamağı düzelt
Düzeltme komutları yalnızca AL (ve AH) üzerinde çalışır; bu yüzden BCD toplama/çıkarma bayt bayt yapılır.

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

AAM · çarpmadan sonra
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”.

AAD · bölmeden önce
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.

Paketlenmiş BCD için 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

Negatif sıcaklıklar

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.

Tam sayı bölmesi

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.

°C → °F geçerli aralık

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 → °C geçerli aralık

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?

KomutCFZFSFOFPFAF
ADD SUB CMP ADC SBB✓✓✓✓✓✓
NEG✓✓✓✓✓✓
INC DEC—✓✓✓✓✓
AND OR XOR TEST0✓✓0✓?
NOT——————
MUL IMUL✓??✓??
DIV IDIV??????
AAA AAS✓????✓
MOV LEA LOOP——————

✓: sonuca göre · 0: temizlenir · —: değişmez · ?: tanımsız.

Özet

Özet

Bayraklar

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.

1. grup

Sonuç ilk işlenende; CMP/TEST yalnız bayrak. Mantıksal komutlar CF = OF = 0.

2. grup

Örtük AL/AX/DX. Bayt: AX = AL × op, AL = AX / op (AH kalan). Sözcük: DX:AX.

3. grup

INC/DEC CF'yi korur; NOT bayrak değiştirmez; NEG ikiye tümleyen.

BCD

AAA/AAS toplama/çıkarma sonrası, AAM çarpma sonrası, AAD bölme öncesi.

Tuzaklar

Bölmeden önce AH/DX hazırla; işaretli veride IMUL/IDIV; aralık taşmalarını bayraklarla denetle.

Özet

Alıştırmalar

  1. MOV AL, 0C0h / ADD AL, 0C0h sonrası AL, CF, OF, SF, ZF, PF nedir?
  2. CMP AL, BL sonrası işaretsiz “AL < BL” hangi bayrakla, işaretli “AL < BL” hangi bayraklarla anlaşılır?
  3. AX = 0FFFFh, BX = 0FFFFh iken MUL BX sonrası DX, AX, CF nedir?
  4. AX = 0100h, BL = 0 iken DIV BL ne olur?
  5. Dizi toplama programını sözcük (DW) dizileri için değiştirin.
  6. Bir bayttaki 1 bitlerini sayan programı SHL/TEST ve döngüyle yazın. PF ile karşılaştırın.
İpuçları / cevaplar
  1. C0h + C0h = 180h → AL = 80h; CF = 1, OF = 0 (−64 + −64 = −128 sığar), SF = 1, ZF = 0, PF = 0 (tek 1 biti).
  2. İşaretsiz: CF = 1. İşaretli: SF ≠ OF.
  3. 65535² = FFFE0001h → DX = FFFEh, AX = 0001h, CF = OF = 1.
  4. Sıfıra bölme → bölme hatası (INT 0).
  5. vec1 dw …, mov ax,[si], add ax,[bx], mov [di],ax; işaretçiler add si,2 ile ilerler.
  6. 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).

Son

Bölüm 6: Aritmetik ve Mantıksal İşlemler
Sonraki bölüm: Bölüm 7: Akış Kontrolü
1 / 1 Sercan KÜLCÜ, Tüm hakları saklıdır.