Bölüm 10: Komut Kümesi

Mikroişlemciler
Komut yapısıMakine koduAdreslemeVeri taşımaAritmetikMantıkKaydırma / döndürmeDizgiDenetim aktarmaİşlemci denetimiBayrak etkileri
Sercan KÜLCÜ · Giresun Üniversitesi · Elektrik-Elektronik Mühendisliği

Giriş

Öğrenme Çıktıları

Komut sınıfları

8086'nın yaklaşık 100 komutunu yedi işlevsel sınıfa ayırmak ve her sınıfın tipik kullanımını açıklamak.

Makine kodu

Opcode, D/W bitleri ve ModR/M baytından bir komutun makine kodunu çıkarmak.

Bayrak etkileri

Hangi komutun hangi bayrağı nasıl değiştirdiğini bilmek; işaretli ve işaretsiz karşılaştırmayı ayırt etmek.

Program izleme

Kaydırma, dizgi, döngü ve çağrı komutları içeren kısa programları yazmaç düzeyinde adım adım izlemek.

Giriş

8086 Komut Kümesine Genel Bakış

1. Veri taşımaYazmaç, bellek, yığın ve G/Ç arasında veri kopyalama.
MOV PUSH POP XCHG IN OUT XLAT LEA LDS LES LAHF SAHF PUSHF POPF
2. AritmetikToplama, çıkarma, çarpma, bölme, BCD düzeltme, işaret genişletme.
ADD ADC INC AAA DAA SUB SBB DEC NEG CMP AAS DAS MUL IMUL AAM DIV IDIV AAD CBW CWD
3. Mantık, kaydırma, döndürmeBit düzeyinde işlemler.
NOT AND OR XOR TEST SHL SAL SHR SAR ROL ROR RCL RCR
4. Dizgi işlemeBellek bloklarını SI/DI ile tarama ve kopyalama.
MOVSB/W CMPSB/W SCASB/W LODSB/W STOSB/W REP REPE REPZ REPNE REPNZ
5. Denetim aktarmaDallanma, döngü, alt program ve kesme.
JMP Jcc (JE JNE JA JB JG JL …) LOOP LOOPE LOOPNE JCXZ CALL RET RETF INT INTO IRET
6. İşlemci denetimiBayrakları kurma/temizleme ve işlemci durumu.
CLC STC CMC CLD STD CLI STI HLT WAIT ESC LOCK NOP

Kaynak sunumdaki altı sınıf; mantık sınıfı kaydırma/döndürme komutlarını da içerir. Bu bölümde her sınıf ayrı ele alınır.

Komut Yapısı

Komut Satırının Yapısı ve İşlenenler

; etiket:  komut   hedef, kaynak   ; yorum
dongu:    add     ax, [bx+2]      ; AX ← AX + bellek

İşlenen türleri

  • Yazmaç: AX, BL, SI, DS …
  • Bellek: [bx], sayi, [bp+si+4]
  • Anlık (immediate): 5, 0Fh, 'A', offset msg
  • Sonuç her zaman hedefe (ilk işlenen) yazılır.
BiçimÖrnekGeçerli?
yazmaç ← yazmaçmov ax, bx✓
yazmaç ↔ bellekmov al, [si]✓
yazmaç/bellek ← anlıkmov byte ptr [di], 5✓
bellek ← bellekmov [di], [si]✗
segment ← anlıkmov ds, 2000h✗
CS hedefmov cs, ax✗
farklı boyutmov ax, bl✗
Bellekten belleğe aktarım bir ara yazmaçla (mov al, [si] / mov [di], al) ya da dizgi komutu movsb ile yapılır. Segment yazmacına değer: mov ax, 2000h / mov ds, ax.

Komut Kodlama

Makine Kodu Biçimi

opcode6 bitDWMOD2REG3R/M3disp düşükdisp yüksekveri düşükveri yüksek1. bayt2. bayt (ModR/M)0 / 1 / 2 bayt yer değiştirme0 / 1 / 2 bayt anlık veriKomut uzunluğu 1–6 bayt; önekler (segment, REP, LOCK) en başa eklenebilir.
D (direction)1: REG alanı hedef; 0: REG alanı kaynak.
W (word)0: bayt (8 bit) işlem; 1: sözcük (16 bit) işlem.
ModR/MMOD işlenenin yazmaç mı bellek mi olduğunu, R/M adres biçimini, REG diğer yazmacı seçer.
Sık kullanılan komutların daha kısa özel biçimleri vardır: inc ax = 40h (1 bayt), mov ax, imm16 = B8h + 2 bayt, add al, imm8 = 04h + 1 bayt.

Komut Kodlama

REG ve MOD Alanları

REGW = 0W = 1SREG
000ALAXES (00)
001CLCXCS (01)
010DLDXSS (10)
011BLBXDS (11)
100AHSP
101CHBP
110DHSI
111BHDI
MODAnlamı
00Bellek, yer değiştirme yok (R/M = 110 ise doğrudan 16 bit adres)
01Bellek + 8 bit yer değiştirme (işaret genişletilir)
10Bellek + 16 bit yer değiştirme
11Yazmaç: R/M alanı da bir REG kodudur
Örnek: mov ax, bx → 8B C3: 100010 1 1 | 11 000 011 (D = 1, hedef REG = AX, R/M = BX). Aynı komut 89 D8 olarak da kodlanabilir (D = 0).

Komut Kodlama

R/M Alanı: Etkin Adres (EA)

R/MMOD = 00MOD = 01MOD = 10Varsayılan segment
000[BX+SI][BX+SI+d8][BX+SI+d16]DS
001[BX+DI][BX+DI+d8][BX+DI+d16]DS
010[BP+SI][BP+SI+d8][BP+SI+d16]SS
011[BP+DI][BP+DI+d8][BP+DI+d16]SS
100[SI][SI+d8][SI+d16]DS
101[DI][DI+d8][DI+d16]DS
110[d16] doğrudan[BP+d8][BP+d16]DS / SS
111[BX][BX+d8][BX+d16]DS
  • Yalnızca BX, BP, SI, DI adres yazmacı olabilir; [ax], [cx], [si+di] geçersizdir.
  • [bp] yazılınca assembler onu [bp+0] (MOD = 01, d8 = 0) olarak kodlar; çünkü MOD = 00, R/M = 110 doğrudan adrese ayrılmıştır.
  • Segment öneki varsayılanı değiştirir: mov al, es:[bx] → önek 26h.

Komut Kodlama

Kodlama Adım Adım: MOV CL, [BX+SI+12h]

OPCODEDWMODREGR/Mdisp81. bayt2. baytMOV CL, [BX+SI+12h]

Komut: bellekteki bir baytı CL'ye taşı. Biçim: MOV reg, r/m (opcode + ModR/M + yer değiştirme).

100010OPCODEDWMODREGR/Mdisp81. bayt2. baytMOV CL, [BX+SI+12h]

MOV r/m ↔ reg ailesinin opcode'u 100010.

100010OPCODE1D0WMODREGR/Mdisp81. bayt2. bayt8AhMOV CL, [BX+SI+12h]

D = 1: REG alanı hedeftir. W = 0: bayt işlem. 1. bayt = 1000 1010b = 8Ah.

100010OPCODE1D0W01MOD001REG000R/Mdisp81. bayt2. bayt8Ah48hMOV CL, [BX+SI+12h]

MOD = 01: bellek + 8 bit yer değiştirme. REG = 001 (CL). R/M = 000 ([BX+SI]). 2. bayt = 01 001 000b = 48h.

100010OPCODE1D0W01MOD001REG000R/M12hdisp81. bayt2. bayt8Ah48h12hMakine kodu: 8A 48 12 (3 bayt)MOV CL, [BX+SI+12h]

12h, 8 bitlik yer değiştirme olarak eklenir. Sonuç: 8A 48 12. Yer değiştirme 16 bit olsaydı MOD = 10 ve 4 bayt olurdu.

Komut Kodlama

Örnek Komutlar ve Uzunlukları

KomutMakine koduBaytNot
nop901aslında xchg ax, ax
inc ax / push bx40 / 531yazmaç kodu opcode'un içinde (40h+r, 50h+r)
mov al, 5B0 052B0h+r, anlık bayt
int 21hCD 212kesme numarası komutta
mov ax, 1234hB8 34 123düşük bayt önce (little-endian)
mov cl, [bx+si+12h]8A 48 123ModR/M + d8
mov es:[bx], al26 88 07326h = ES öneki
add [bx+di+1000h], dx01 91 00 104MOD = 10, d16
mov word ptr [1234h], 5678hC7 06 34 12 78 566en uzun biçim: d16 + imm16
rep movsbF3 A42F3h = REP öneki

Önekler: 26h ES, 2Eh CS, 36h SS, 3Eh DS (segment); F3h REP/REPE, F2h REPNE; F0h LOCK. emu8086'da makine kodunu görmek için derledikten sonra listing (.lst) dosyasına bakılabilir.

Adresleme Modları

Adresleme Modları (Özet)

ModÖrnekİşlenen nerede?
Anlıkmov ax, 1234hkomutun içinde
Yazmaçmov ax, bxyazmaçta; bellek erişimi yok (en hızlı)
Doğrudanmov al, [0120h], mov al, sayiEA = komuttaki adres (DS)
Yazmaç dolaylımov al, [bx], [si], [di]EA = yazmaç (DS)
Tabanlımov al, [bx+4], [bp+4]EA = BX/BP + yer değiştirme (BP → SS)
İndislimov al, dizi[si]EA = SI/DI + yer değiştirme
Tabanlı-indislimov al, [bx+si+4]EA = taban + indis (+ yer değiştirme)
Örtükcbw, movsb, xlatyazmaçlar komutun tanımında sabit
G/Ç portuin al, 60h / out dx, alsabit 8 bit port ya da DX

Ayrıntılar Bölüm 4: Bellek Erişimi'nde. Fiziksel adres = segment × 16 + EA (20 bit).

Adresleme Modları

Fiziksel Adres Hesabı Adım Adım

DS = 2000h, BX = 0100h, SI = 0020h, SS = 3000h, BP = FFF0h

mov al, [bx+si+4]: tabanlı-indisli + d8 → BP yok, varsayılan segment DS.
EA = BX + SI + 4 = 0100h + 0020h + 0004h = 0124h (16 bit).
Fiziksel adres = DS × 10h + EA = 20000h + 0124h = 20124h.
mov ax, [bp+2]: BP kullanıldığı için segment SS. EA = FFF0h + 2 = FFF2h.
Fiziksel adres = 30000h + FFF2h = 3FFF2h; AL ← [3FFF2h], AH ← [3FFF3h] (little-endian).
Dikkat: EA 16 bitte sarar. BX = FFFFh, SI = 0002h ise EA = 1 0001h değil 0001h olur.

Veri Taşıma

Veri Taşıma Komutları

KomutİşlemÖrnek
MOV h, kh ← k (kopyalama)mov bx, [si]
PUSH k / POP hSP ← SP−2, [SS:SP] ← k / h ← [SS:SP], SP ← SP+2push ax
XCHG a, ba ↔ b (biri yazmaç olmalı)xchg al, [bx]
IN / OUTAL/AX ↔ G/Ç portuin al, 60h
XLATAL ← [DS:BX + AL]tablo çevirisi
LEA r, mr ← m'nin adresi (EA)lea si, metin
LDS / LES r, mr ← [m], DS/ES ← [m+2] (uzak işaretçi)les di, uzak
LAHF / SAHFAH ← FLAGS düşük bayt / tersi
PUSHF / POPFFLAGS'ı yığına at / yığından al
Veri taşıma komutları bayrakları etkilemez; istisnalar SAHF ve POPF'tur (bayrakları doğrudan yazarlar).

Veri Taşıma · Kodu adım adım çalıştır

Kod İzleme: PUSH / POP ile Takas ve XCHG

AX'e anlık değer yüklenir: AX = 1234h. MOV hiçbir bayrağı etkilemez.

BX = 5678h. Yığın henüz boş: COM programında SP = FFFEh.

push ax: önce SP ← SP − 2 = FFFCh, sonra [SS:FFFCh] ← 1234h (düşük bayt 34h küçük adreste).

push bx: SP = FFFAh, yığının üstünde artık 5678h var.

pop ax: üstteki sözcük okunur → AX = 5678h, sonra SP ← SP + 2 = FFFCh. Son giren ilk çıkar (LIFO).

pop bx: BX = 1234h, SP = FFFEh. İki PUSH + ters sırada iki POP = takas.

xchg ah, al: AX'in iki baytı yer değiştirir: 5678h → 7856h. Ek yazmaç gerekmez.

xchg ax, bx: AX ↔ BX. AX = 1234h, BX = 7856h. XCHG AX, r16 tek baytlık bir komuttur (90h+r).

Yığın dengeli (SP = FFFEh) olduğu için ret programı sonlandırır.

org 100h
mov ax, 1234h
mov bx, 5678h
push ax          ; SP -= 2, [SP] = AX
push bx
pop ax           ; AX = son giren
pop bx           ; BX = 1234h
xchg ah, al      ; baytları takas et
xchg ax, bx
ret

Veri Taşıma

G/Ç Komutları: IN ve OUT

  • 8086'nın bellekten ayrı 64 K'lık G/Ç adres alanı vardır (M/IO̅ ucu).
  • Veri yalnızca AL (8 bit) ya da AX (16 bit) üzerinden aktarılır.
  • Sabit port: 00h–FFh, komutun içinde.
  • Değişken port: 0000h–FFFFh, DX ile.
  • Bayrakları etkilemez.
in  al, 60h      ; port 60h'tan bayt oku
out 43h, al      ; port 43h'e yaz

mov dx, 3F8h     ; 255'ten büyük port
in  al, dx       ; DX ile adreslenir
out dx, ax       ; 16 bit yaz

in  bl, 60h      ; HATA: yalnız AL/AX
out 3F8h, al     ; HATA: DX gerekli
emu8086'daki sanal aygıtlar (trafik lambası, step motor, LED ekran) bu komutlarla sürülür; ayrıntılar Bölüm 9: Aygıt Kontrolü'nde.

Veri Taşıma · Kodu adım adım çalıştır

Kod İzleme: XLAT ile Baytı Onaltılı Yazdırma

BX, çeviri tablosunun başlangıç bağıl konumunu (offset) alır: BX = 011Dh.

Yazdırılacak bayt: AL = 3Ch (0011 1100b).

8086'da 1'den büyük kaydırma sayısı CL ile verilir.

shr al, cl: 0011 1100 → 0000 0011. AL = 03h (üst dörtlü).

xlat: AL ← [DS:BX + AL] = tablo[3] = '3' (33h).

Karakter DL'ye kopyalanır (INT 21h/02h parametresi).

AH = 02h: DOS karakter yaz servisi.

DOS ekrana '3' yazar (AL de DL'nin değerini alır).

Aynı bayt yeniden alınır: AL = 3Ch.

and al, 0Fh: üst dörtlü maskelenir → AL = 0Ch.

tablo[12] = 'C' (43h).

DL = 43h. AH hâlâ 02h olduğundan yeniden yüklemeye gerek yok.

Ekrana 'C' yazılır → çıktı 3C.

Program biter. XLAT, en fazla 256 baytlık tablolarla tek komutta çeviri yapar.

org 100h
mov bx, offset tablo
mov al, sayi       ; AL = 3Ch
mov cl, 4
shr al, cl         ; üst dörtlü
xlat               ; AL = [BX+AL]
mov dl, al
mov ah, 2
int 21h            ; DL'yi yaz
mov al, sayi
and al, 0Fh        ; alt dörtlü
xlat
mov dl, al
int 21h
ret
sayi  db 3Ch
tablo db '0123456789ABCDEF'

Veri Taşıma

Adres Yükleme: LEA, LDS, LES

  • lea si, metin ≡ mov si, offset metin; fark: LEA çalışma anında hesaplanan adresleri de verir: lea si, [bx+di+4].
  • LEA belleğe erişmez ve bayrakları etkilemez; bu yüzden toplama için de kullanılabilir: lea ax, [bx+si] → AX = BX + SI.
  • lds si, ptr: SI ← [ptr], DS ← [ptr+2]. les di, ptr aynı işi ES ile yapar.
  • Uzak işaretçi (far pointer) bellekte bağıl konum önce, segment sonra saklanır.
mov bx, 0010h
mov di, 0004h
lea ax, [bx+di+2]  ; AX = 0016h
mov ax, [bx+di+2]  ; AX = [0016h]

; ekran belleği: B800:0000
ekran dw 0000h, 0B800h
les di, ekran      ; DI=0000h ES=B800h
mov al, 'A'
stosb             ; köşeye 'A'
LEA adresi, MOV içeriği verir: lea ax, [bx+di+2] ile mov ax, [bx+di+2] arasındaki fark sınavlarda sık sorulur.

Veri Taşıma

Bayrak Yazmacına Erişim

–15–14–13–12OF11DF10IF9TF8SF7ZF6–5AF4–3PF211CF0düşük bayt → LAHF / SAHF (AH)denetim bayrakları: DF IF TF
LAHF / SAHFAH ↔ FLAGS'ın düşük baytı: SF ZF – AF – PF – CF. 8080 uyumluluğu için vardır; OF, DF, IF, TF'ye dokunmaz.
PUSHF / POPF16 bitlik FLAGS'ın tamamı yığına atılır / geri alınır. Bir alt programın bayrakları bozmaması ya da TF'yi değiştirmek için kullanılır.
pushf              ; bayrakları sakla
pop ax             ; AX = FLAGS
or  ax, 0100h       ; TF (bit 8) = 1 → tek adım kipi
push ax
popf               ; TF'yi doğrudan kuran bir komut yoktur

Aritmetik

Aritmetik Komutlar

GrupKomutlarAçıklama
ToplamaADD ADC INCADC eldeyi (CF) de ekler; INC CF'yi değiştirmez
ÇıkarmaSUB SBB DEC NEG CMPSBB ödüncü (CF) de çıkarır; NEG = 0 − h; CMP sonucu yazmaz
ÇarpmaMUL IMULişaretsiz / işaretli; örtük AL veya AX
BölmeDIV IDIVişaretsiz / işaretli; bölüm + kalan
BCD düzeltmeDAA DAS AAA AAS AAM AADikili sonucu ondalığa düzeltir
İşaret genişletmeCBW CWDAL → AX, AX → DX:AX
İşlemci toplamayı ve çıkarmayı tek bir devreyle yapar; sayının işaretli mi işaretsiz mi olduğunu bilmez. Bu yüzden her iki yorum için bayrak üretir: CF işaretsiz taşmayı, OF işaretli taşmayı gösterir.

Aritmetik

Durum Bayrakları Ne Anlatır?

Bayrak1 olur, eğer…8 bit örnek
CFen anlamlı bitten elde çıktı (toplama) ya da ödünç alındı (çıkarma) → işaretsiz taşmaFFh + 01h = 1 00h
OFişaretli sonuç aralık dışı: iki pozitifin toplamı negatif ya da iki negatifin toplamı pozitif7Fh + 01h = 80h
ZFsonuç sıfır05h − 05h
SFsonucun en anlamlı biti 1 (işaretli yorumda negatif)05h − 07h = FEh
PFsonucun düşük baytındaki 1'lerin sayısı çift03h (2 adet 1)
AFbit 3'ten bit 4'e elde / ödünç (BCD düzeltmesi için)08h + 08h
Kural: OF = (bit 6'dan bit 7'ye giren elde) XOR (bit 7'den çıkan elde). Toplamada işaretleri farklı iki sayı asla taşma üretmez.

Aritmetik

Bayrak Hesaplayıcı (8 bit)

İki onaltılı bayt girin. Deneyin: 7F+01, FF+01, 80+80, 05−07, 38+45 (AF), 0F AND F0.

Aritmetik · Kodu adım adım çalıştır

Kod İzleme: ADD, SUB, NEG, CMP ve Bayraklar

AL = 7Fh = 0111 1111b: işaretli olarak en büyük pozitif bayt (+127).

7Fh + 1 = 80h. İşaretsiz: 128 (doğru, CF = 0). İşaretli: +127 + 1 = −128 → OF = 1 (taşma). SF = 1, bit 3'ten elde → AF = 1.

BL = FFh (işaretsiz 255, işaretli −1).

FFh + 1 = 1 00h → BL = 00h, CF = 1, ZF = 1. İşaretli: −1 + 1 = 0, doğru → OF = 0.

CL = 05h.

5 − 7 = −2 = FEh. Ödünç alındı → CF = 1; SF = 1. İşaretli sonuç doğru → OF = 0.

neg cl: 0 − FEh = 02h. İşlenen sıfır olmadığından CF = 1.

cmp cl, 2: 2 − 2 hesaplanır ama sonuç yazılmaz. ZF = 1 → je dallanır.

CMP yalnızca bayrakları değiştirir; CL hâlâ 02h.

org 100h
mov al, 7Fh
add al, 1        ; +127 + 1
mov bl, 0FFh
add bl, 1        ; 255 + 1
mov cl, 5
sub cl, 7        ; 5 - 7
neg cl
cmp cl, 2
ret

Aritmetik · Kodu adım adım çalıştır

Kod İzleme: ADC ile 32 Bitlik Toplama

Birinci 32 bitlik sayının düşük sözcüğü: AX = F00Fh.

Yüksek sözcük: DX = 1234h. Birlikte DX:AX = 1234F00Fh.

İkinci sayının düşük sözcüğü BX = 2001h.

Yüksek sözcük CX = 0001h → CX:BX = 00012001h.

add ax, bx: F00Fh + 2001h = 1 1010h. 16 bite sığmaz → AX = 1010h, CF = 1 (elde).

adc dx, cx: 1234h + 0001h + CF = 1236h. Sonuç DX:AX = 12361010h.

inc ax: AX = 1011h. INC/DEC CF'yi değiştirmez; döngü sayaçlarında elde bilgisini korur.

Bitti: 1234F00Fh + 00012001h = 12361010h, sonra +1.

org 100h
mov ax, 0F00Fh     ; DX:AX = 1234F00Fh
mov dx, 1234h
mov bx, 2001h      ; CX:BX = 00012001h
mov cx, 0001h
add ax, bx         ; düşük sözcükler
adc dx, cx         ; yüksek + CF
inc ax             ; CF etkilenmez
ret

Aritmetik

Çıkarma Ailesi

KomutİşlemNot
sub h, kh ← h − kCF = ödünç
sbb h, kh ← h − k − CFçok sözcüklü çıkarma
dec hh ← h − 1CF değişmez
neg hh ← 0 − hikiye tümleyen; h ≠ 0 ise CF = 1
cmp h, kh − k (yazılmaz)yalnızca bayraklar
; 32 bit: DX:AX ← DX:AX − CX:BX
sub ax, bx    ; düşük sözcük
sbb dx, cx    ; yüksek − ödünç

; mutlak değer
cmp ax, 0
jge pozitif
neg ax        ; −5 → 5
pozitif:
cmp a, b sonrası: a = b ⇒ ZF = 1; işaretsiz a < b ⇒ CF = 1; işaretli a < b ⇒ SF ≠ OF. Koşullu dallanmalar bu bayrakları okur.

NEG −128'de (80h) sonuç yine 80h olur ve OF = 1: bu değerin 8 bitte pozitif karşılığı yoktur.

Aritmetik

Çarpma ve Bölme: Örtük Yazmaçlar

MUL r/m8AL×r/m8AXMUL r/m16AX×r/m16DXAXDIV r/m8AX÷r/m8ALAHbölümkalanDIV r/m16DXAX÷r/m16AXDXbölümkalan
MUL / IMUL kaynakTek işlenen alır (yazmaç ya da bellek, anlık olamaz). Sonuç her zaman çift genişlikte. Üst yarı sıfır değilse (IMUL'da işaret uzantısı değilse) CF = OF = 1.
DIV / IDIV kaynakBölüm hedefe sığmazsa ya da bölen 0 ise işlemci INT 0 (bölme hatası) üretir. IDIV'de kalanın işareti bölünenin işaretidir.
mov al, 80h  mov bl, 4  mul bl    ; AX = 0200h, CF = OF = 1 (AH ≠ 0)
mov al, -2   mov bl, 3  imul bl   ; AX = FFFAh (−6), CF = OF = 0
mov ax, 1000h mov bl, 2 div bl    ; bölüm 800h > FFh → bölme hatası!

Aritmetik · Kodu adım adım çalıştır

Kod İzleme: DIV ile Sayıyı Ondalık Yazdırma

Yazdırılacak sayı: 305 = 0131h.

Bölen BX = 10 (000Ah).

xor cx, cx: CX = 0. Kendisiyle XOR en kısa sıfırlama yoludur.

16 bitlik DIV, bölünen olarak DX:AX'i kullanır; DX mutlaka sıfırlanmalı.

305 ÷ 10 → AX = 30 (001Eh), kalan DX = 5 (birler basamağı).

Kalan yığına atılır: basamaklar ters sırada üretilir, yığın sırayı düzeltir.

Basamak sayacı CX = 0001h.

test ax, ax: AX = 001Eh → ZF = 0.

AX ≠ 0 → bol'e dön.

16 bitlik DIV, bölünen olarak DX:AX'i kullanır; DX mutlaka sıfırlanmalı.

30 ÷ 10 → AX = 3, kalan DX = 0 (onlar basamağı).

0 yığına atılır.

Basamak sayacı CX = 0002h.

test ax, ax: AX = 0003h → ZF = 0.

AX ≠ 0 → bir tur daha.

16 bitlik DIV, bölünen olarak DX:AX'i kullanır; DX mutlaka sıfırlanmalı.

3 ÷ 10 → AX = 0, kalan DX = 3 (yüzler basamağı).

3 yığına atılır; üstte artık en anlamlı basamak var.

Basamak sayacı CX = 0003h.

test ax, ax: AX = 0000h → ZF = 1.

AX = 0 → döngüden çık. CX = 3 basamak.

pop dx: üstteki basamak DX = 0003h.

'0' (30h) eklenerek rakam ASCII'ye çevrilir: DL = 33h.

AH = 02h (karakter yaz).

Rakam ekrana yazılır.

loop yaz: CX = 0002h, sıfır değil → tekrar.

pop dx: üstteki basamak DX = 0000h.

'0' (30h) eklenerek rakam ASCII'ye çevrilir: DL = 30h.

AH = 02h (karakter yaz).

Rakam ekrana yazılır.

CX = 0001h → tekrar.

pop dx: üstteki basamak DX = 0005h.

'0' (30h) eklenerek rakam ASCII'ye çevrilir: DL = 35h.

AH = 02h (karakter yaz).

Rakam ekrana yazılır.

CX = 0 → döngü biter. Ekranda 305.

Bölme–kalan yöntemi her tabana uygulanabilir (bölen 2 → ikili, 16 → onaltılı).

org 100h
mov ax, 305
mov bx, 10
xor cx, cx       ; basamak sayacı
bol:
xor dx, dx       ; DX:AX bölünen
div bx           ; AX=bölüm DX=kalan
push dx
inc cx
test ax, ax
jnz bol
yaz:
pop dx
add dl, '0'      ; rakam → ASCII
mov ah, 2
int 21h
loop yaz
ret

Aritmetik

İşaret Genişletme: CBW ve CWD

  • cbw: AL'nin işaret bitini AH'ye kopyalar (AL → AX).
  • cwd: AX'in işaret bitini DX'e kopyalar (AX → DX:AX).
  • İşaretli bölmeden (IDIV) önce bölünen bu komutlarla genişletilir; işaretsiz bölmede ise üst yarı sıfırlanır (xor dx, dx / mov ah, 0).
  • Bayrakları etkilemez.
ÖnceKomutSonra
AL = 05hcbwAX = 0005h
AL = F6h (−10)cbwAX = FFF6h
AX = FFF6hcwdDX = FFFFh
; −10 ÷ 3 (işaretli)
mov al, -10    ; AL = F6h
cbw            ; AX = FFF6h
mov bl, 3
idiv bl        ; AL = FDh (−3)
               ; AH = FFh (−1)

; yanlış: mov ah, 0
; AX = 00F6h = +246
; idiv bl → AL = 52h (82)

IDIV bölümü sıfıra doğru keser: −10 / 3 = −3, kalan −1 (−3 × 3 − 1 = −10).

Aritmetik

BCD Düzeltme Komutları

KomutNe zaman?Örnek
DAApaketli BCD toplamadan sonra38h + 45h = 7Dh → 83h
DASpaketli BCD çıkarmadan sonra83h − 38h = 4Bh → 45h
AAApaketsiz/ASCII toplamadan sonra'8' + '5' = 6Dh → AX = 0103h (AH+1)
AASpaketsiz/ASCII çıkarmadan sonra'3' − '5' = FEh → AL = 08h, AH−1, CF = 1
AAMpaketsiz çarpmadan sonra7 × 8 = 38h → AH = 05, AL = 06
AADpaketsiz bölmeden önceAX = 0506h → AL = 38h (56), AH = 0
Paketli BCDBir baytta iki ondalık hane: 45 → 45h (0100 0101).
Paketsiz BCDBir baytta bir hane: 45 → 04h 05h; ASCII'de 34h 35h.

Aritmetik · Kodu adım adım çalıştır

Kod İzleme: DAA ve AAM ile Ondalık Sonuç

Paketli BCD: 38h, ondalık 38 anlamına gelir.

İkili toplama: 38h + 45h = 7Dh. Alt dörtlü Dh > 9 → geçerli BCD değil.

daa: alt dörtlü > 9 → +06h: 7Dh + 6 = 83h. 38 + 45 = 83 ✓.

Yeni örnek: BCD 79.

79h + 35h = AEh. Bit 3'ten elde yok → AF = 0.

daa: Eh > 9 → +06h (B4h); sonra AL > 9Fh → +60h → 14h, CF = 1. 79 + 35 = 114 ✓.

AAM ikili sayıyla çalışır: AL = 47 = 2Fh.

aam: AH = AL ÷ 10 = 4, AL = AL mod 10 = 7 → AX = 0407h (paketsiz BCD).

Her iki bayta 30h eklenir: AX = 3437h = '4','7'.

Rakamlar BX'te saklanır, çünkü INT 21h/02h AL'yi değiştirir.

DL = '4'.

AH = 02h.

Ekrana 4.

DL = '7'.

Ekrana 7 → çıktı 47.

AAM, 0–99 arası bir değeri iki haneli yazdırmanın en kısa yoludur (saat, tarih).

org 100h
mov al, 38h      ; BCD 38
add al, 45h      ; + BCD 45
daa              ; ondalık düzelt
mov al, 79h
add al, 35h
daa
mov al, 47       ; ikili 2Fh
aam              ; AH=onlar AL=birler
add ax, 3030h    ; → ASCII
mov bx, ax
mov dl, bh
mov ah, 2
int 21h
mov dl, bl
int 21h
ret

Mantık İşlemleri

Mantık Komutları

KomutİşlemTipik kullanımÖrnek
ANDh ← h ∧ kbit temizleme (maskeleme)and al, 0Fh
ORh ← h ∨ kbit kurmaor al, 80h
XORh ← h ⊕ kbit tersleme, sıfırlamaxor ax, ax
NOTh ← ¬hbirler tümleyeninot bl
TESTh ∧ k (yazılmaz)bit sınamatest al, 1 → çift/tek
BayraklarAND, OR, XOR, TEST: CF = OF = 0; SF, ZF, PF sonuca göre; AF tanımsız. NOT hiçbir bayrağı değiştirmez.
Harf dönüşümü'a' = 61h, 'A' = 41h: yalnız bit 5 farklı. and al, 0DFh büyük, or al, 20h küçük harf.
Rakam ↔ sayıand al, 0Fh: '7' (37h) → 7. or al, 30h: 7 → '7'.

Mantık İşlemleri · Kodu adım adım çalıştır

Kod İzleme: AND, OR, XOR, TEST, NOT

AL = 'g' = 67h = 0110 0111b. Küçük ve büyük harf yalnızca bit 5'te farklıdır.

and al, 0DFh (1101 1111b): bit 5 temizlenir → 47h = 'G'. AND sonrası CF = OF = 0.

or al, 20h: bit 5 kurulur → 67h = 'g' (küçük harfe çevirme).

xor al, 20h: bit 5 terslenir → 47h = 'G'. XOR harf büyüklüğünü değiştirir.

BL = 1011 0101b = B5h.

test = sonucu yazmayan AND. Bit 3 = 0 → B5h AND 08h = 0 → ZF = 1.

Bit 7 = 1 → sonuç 80h ≠ 0 → ZF = 0, SF = 1. BL değişmedi.

not bl: tüm bitler terslenir → 0100 1010b = 4Ah. NOT hiçbir bayrağı etkilemez.

xor ax, ax: AX = 0, ZF = 1, CF = 0. MOV AX, 0'dan kısa (2 bayt).

Son.

org 100h
mov al, 'g'       ; 67h
and al, 0DFh      ; bit 5 = 0
or  al, 20h       ; bit 5 = 1
xor al, 20h       ; bit 5 tersle
mov bl, 10110101b
test bl, 00001000b
test bl, 10000000b
not bl
xor ax, ax
ret

Kaydırma ve Döndürme

Kaydırma: SHL/SAL, SHR, SAR

b7b6b5b4b3b2b1b0CF0
SHL/SAL: sola kaydır, sağdan 0 girer, çıkan bit CF'ye. Her adım × 2.
b7b6b5b4b3b2b1b0CF0
SHR: mantıksal sağa kaydır, soldan 0 girer. İşaretsiz ÷ 2.
b7b6b5b4b3b2b1b0CFişaret biti korunur
SAR: aritmetik sağa kaydır, işaret biti korunur. İşaretli ÷ 2 (−∞'a yuvarlar).
Kaydırma sayısı8086'da yalnızca 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 ile IDIV farklı yuvarlar: −7 (F9h) sar 1 → FCh = −4; idiv 2 → −3.

Kaydırma ve Döndürme

Döndürme: ROL, ROR, RCL, RCR

b7b6b5b4b3b2b1b0CF
ROL: sola döndür; b7 hem b0'a hem CF'ye gider.
b7b6b5b4b3b2b1b0CF
ROR: sağa döndür; b0 hem b7'ye hem CF'ye gider.
b7b6b5b4b3b2b1b0CF
RCL: CF üzerinden sola döndür (9 bitlik halka).
b7b6b5b4b3b2b1b0CF
RCR: CF üzerinden sağa döndür.
Döndürmede bit kaybolmaz. Yalnızca CF ve (sayı 1 iken) OF değişir; SF, ZF, PF etkilenmez. RCL/RCR çok sözcüklü kaydırmalarda kullanılı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'yi art arda uygulayıp sayının iki katına çıktığını, SAR'ın işareti koruduğunu gözleyin.

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: kağıt üzerindeki çarpmada olduğu gibi bitleri tek tek inceleriz.

4 bitlik çarpan için 4 tur.

shr dl, 1: çıkan bit 1 → CF = 1.

CF = 1 → dallanma 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 dallanır.

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 × 10 = AX×8 + AX×2
shl ax, 1      ; AX × 2
mov bx, ax     ; sakla
shl ax, 1      ; AX × 4
shl ax, 1      ; AX × 8
add ax, bx     ; ×8 + ×2

; işaretsiz ÷ 16, kalan
mov bx, ax
and bx, 000Fh  ; kalan = alt 4 bit
mov cl, 4
shr ax, cl     ; bölüm
  • 8086'da mul 70–133, div 80–162 saat çevrimi sürer; bir shl reg, 1 yalnızca 2 çevrim.
  • 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: and ile alt n bit.
  • İşaretli bölmede SAR kullanılır; negatif sayılarda yuvarlama farkına dikkat.
Örnek: AX = 25 → 50 → (BX = 50) → 100 → 200 → 200 + 50 = 250.

Dizgi İşleme

Dizgi (String) Komutları

KomutİşlemGüncellenenBayrak
MOVSB / MOVSW[ES:DI] ← [DS:SI]SI, DI–
CMPSB / CMPSW[DS:SI] − [ES:DI]SI, DICMP gibi
SCASB / SCASWAL/AX − [ES:DI]DICMP gibi
LODSB / LODSWAL/AX ← [DS:SI]SI–
STOSB / STOSW[ES:DI] ← AL/AXDI–
Kaynak / hedefKaynak DS:SI (segment öneki ile değişebilir), hedef her zaman ES:DI.
Yön bayrağıcld → DF = 0, adresler artar; std → DF = 1, azalır.
AdımB (bayt) sürümünde ±1, W (sözcük) sürümünde ±2.

EXE programlarında ES ayrıca ayarlanmalıdır (mov ax, @data / mov es, ax); COM programlarında DS = ES = CS'dir.

Dizgi İşleme

Yineleme Önekleri: REP, REPE, REPNE

ÖnekSürdürme koşuluKullanım
REPCX ≠ 0MOVS, STOS
REPE / REPZCX ≠ 0 ve ZF = 1CMPS, SCAS: "eşitken"
REPNE / REPNZCX ≠ 0 ve ZF = 0CMPS, SCAS: "eşit değilken"
1. CX = 0 ise dur (komut hiç çalışmayabilir).
2. Dizgi komutunu bir kez yürüt, SI/DI'yi güncelle.
3. CX ← CX − 1 (bayraklar değişmez).
4. REPE/REPNE ise ZF koşulunu sına; sağlanmıyorsa dur. Değilse 1'e dön.
; 100 baytlık blok kopyalama
cld
lea si, kaynak
lea di, hedef
mov cx, 100
rep movsb

; ekranı boşlukla doldur
mov ax, 0B800h
mov es, ax
xor di, di
mov ax, 0720h   ; ' ' + öznitelik
mov cx, 2000    ; 80×25
rep stosw

Dizgi İşleme · Kodu adım adım çalıştır

Kod İzleme: MOVSB ile Kopyalama

DF = 0: ileri yönde kopyalama.

SI = 0110h: kaynak dizgi.

DI = 0114h: hedef alan ('....').

Kopyalanacak bayt sayısı CX = 4.

movsb: bir bayt kopyalanır; SI = 0111h, DI = 0115h. Bayraklar değişmez.

CX = 0003h.

movsb: bir bayt kopyalanır; SI = 0112h, DI = 0116h. Bayraklar değişmez.

CX = 0002h.

movsb: bir bayt kopyalanır; SI = 0113h, DI = 0117h. Bayraklar değişmez.

CX = 0001h.

movsb: bir bayt kopyalanır; SI = 0114h, DI = 0118h. Bayraklar değişmez.

CX = 0000h.

hedef = 'ABCD'. mov cx, 4 + rep movsb aynı işi tek komutla yapar.

org 100h
cld
lea si, kaynak     ; DS:SI kaynak
lea di, hedef      ; ES:DI hedef
mov cx, 4
kopya:
movsb              ; [DI]←[SI], SI++, DI++
loop kopya         ; = rep movsb
ret
kaynak db 'ABCD'
hedef  db 4 dup('.')

Dizgi İşleme · Kodu adım adım çalıştır

Kod İzleme: LODSB + STOSB ile Büyük Harfe Çevirme

cld: DF = 0 → dizgi komutları SI/DI'yi artırır.

SI kaynağı gösterir: SI = 0111h (metin).

Hedef aynı dizgi: DI = 0111h. COM programında ES = DS olduğundan ES:DI aynı yeri gösterir.

5 karakter işlenecek.

lodsb: AL = [DS:SI] = 6Dh, ardından SI = 0112h.

Bit 5 temizlenir: AL = 4Dh.

stosb: [ES:DI] ← AL, ardından DI = 0112h.

CX = 0004h.

lodsb: AL = [DS:SI] = 69h, ardından SI = 0113h.

Bit 5 temizlenir: AL = 49h.

stosb: [ES:DI] ← AL, ardından DI = 0113h.

CX = 0003h.

lodsb: AL = [DS:SI] = 6Bh, ardından SI = 0114h.

Bit 5 temizlenir: AL = 4Bh.

stosb: [ES:DI] ← AL, ardından DI = 0114h.

CX = 0002h.

lodsb: AL = [DS:SI] = 72h, ardından SI = 0115h.

Bit 5 temizlenir: AL = 52h.

stosb: [ES:DI] ← AL, ardından DI = 0115h.

CX = 0001h.

lodsb: AL = [DS:SI] = 6Fh, ardından SI = 0116h.

Bit 5 temizlenir: AL = 4Fh.

stosb: [ES:DI] ← AL, ardından DI = 0116h.

CX = 0000h.

metin = 'MIKRO'. LODS/STOS çifti diziyi yerinde dönüştürmenin tipik kalıbıdır.

org 100h
cld               ; DF = 0: ileri
lea si, metin
mov di, si        ; aynı yere yaz
mov cx, 5
don:
lodsb             ; AL = [SI], SI++
and al, 0DFh      ; büyük harf
stosb             ; [DI] = AL, DI++
loop don
ret
metin db 'mikro'

Dizgi İşleme · Kodu adım adım çalıştır

Kod İzleme: REPNE SCASB ile Karakter Arama

İleri yönde tarama.

DI = 0114h: taranacak dizgi ES:DI'de olmalı.

En fazla 7 karşılaştırma.

Aranan karakter AL = 'h' (68h).

repne scasb: 'm','e','r','h' ile karşılaştırılır; 4. karşılaştırmada ZF = 1 olur ve durur. Her turda DI++ ve CX−−: DI = 0118h, CX = 0003h.

ZF = 1 (bulundu) → dallanma yok.

DI eşleşmeden bir sonrayı gösterir; geri al: DI = 0117h.

Başlangıç çıkarılır: DI = 3 → 'h' 3. indiste (0'dan sayarak).

Bulunamasaydı CX = 0 ve ZF = 0 ile çıkılır, jne yok dallanırdı.

org 100h
cld
lea di, metin
mov cx, 7          ; uzunluk
mov al, 'h'        ; aranan
repne scasb        ; ara
jne yok
dec di             ; bulunan konum
sub di, offset metin
yok:
ret
metin db 'merhaba'

Denetim Aktarma

Koşulsuz Dallanma: JMP

TürKodErimÖrnek
Kısa (short)EB d8−128 … +127 baytjmp short dongu
Yakın (near)E9 d16aynı kesim, ±32 Kjmp basla
Uzak (far)EA IP CSherhangi bir kesimjmp far ptr hedef
Dolaylı yakınFF /4IP ← yazmaç/bellekjmp bx, jmp tablo[bx]
Dolaylı uzakFF /5CS:IP ← bellek (4 bayt)jmp dword ptr [si]
  • Kısa ve yakın dallanmalar görelidir: hedef = sonraki komutun adresi + yer değiştirme. Bu sayede kod bellekte taşınabilir.
  • Dolaylı dallanma ile atlama tablosu (switch-case) kurulur: shl bx, 1 / jmp tablo[bx].
  • JMP, LOOP, CALL, RET bayrakları etkilemez.

Denetim Aktarma

Koşullu Dallanmalar (Jcc)

İşaretsiz karşılaştırma
JA / JNBECF = 0 ve ZF = 0 (>)
JAE / JNB / JNCCF = 0 (≥)
JB / JNAE / JCCF = 1 (<)
JBE / JNACF = 1 veya ZF = 1 (≤)
İşaretli karşılaştırma
JG / JNLEZF = 0 ve SF = OF (>)
JGE / JNLSF = OF (≥)
JL / JNGESF ≠ OF (<)
JLE / JNGZF = 1 veya SF ≠ OF (≤)
Tek bayrak / eşitlik
JE / JZZF = 1
JNE / JNZZF = 0
JS / JNSSF = 1 / SF = 0
JO / JNOOF = 1 / OF = 0
JP / JPEPF = 1 (çift eşlik)
JNP / JPOPF = 0 (tek eşlik)
JCXZCX = 0 (bayrak değil)
Akılda tutma: Above/Below → işaretsiz; Greater/Less → işaretli. N = not, E = equal.

Denetim Aktarma · Kodu adım adım çalıştır

Kod İzleme: Aynı Bayt, İki Farklı Karşılaştırma

BL = FFh. İşaretsiz yorum 255, işaretli yorum −1.

FFh − 01h = FEh: CF = 0 (ödünç yok), ZF = 0, SF = 1, OF = 0.

jg: ZF = 0 ve SF = OF ister. SF ≠ OF → −1 > 1 değil, dallanmaz.

DL = 'K' (küçük).

Ortak yazdırma koduna atla.

AH = 02h: karakter yaz.

İşaretli karşılaştırmanın sonucu ekranda: K.

Aynı karşılaştırma yeniden (INT 21h bayrakları değiştirmiş olabilir).

ja: CF = 0 ve ZF = 0 ister → 255 > 1, dallanır.

DL = 'B' (büyük).

Çıktı KB: aynı bit dizisi, farklı dallanma.

İşaretli veride JG/JGE/JL/JLE, işaretsiz veride JA/JAE/JB/JBE kullanılır.

org 100h
mov bl, 0FFh
cmp bl, 1
jg isaretli       ; -1 > 1 ?
mov dl, 'K'
jmp yaz1
isaretli:
mov dl, 'B'
yaz1:
mov ah, 2
int 21h
cmp bl, 1
ja isaretsiz      ; 255 > 1 ?
mov dl, 'K'
jmp yaz2
isaretsiz:
mov dl, 'B'
yaz2:
int 21h
ret

Denetim Aktarma

8086'da Koşullu Dallanma Erimi

  • 8086'da tüm Jcc komutları kısadır: 2 bayt, hedef −128…+127 bayt içinde olmalı.
  • Hedef uzaksa assembler "relative jump out of range" hatası verir.
  • Çözüm: koşulu tersine çevir ve yakın JMP ile atla.
  • 80386 ve sonrasında 16/32 bit yer değiştirmeli Jcc (0F 8x) vardır.
; hatalı (hedef çok uzak)
cmp al, 0Dh
je  bitis        ; > 127 bayt

; düzeltilmiş
cmp al, 0Dh
jne devam       ; ters koşul, kısa
jmp bitis       ; yakın, ±32 K
devam:
Örnek kod: EB FE = "kendine atla" (sonsuz döngü), çünkü FEh = −2 ve komut 2 bayttır.

Denetim Aktarma

Döngü Komutları

KomutİşlemDallanma koşulu
LOOP hCX ← CX − 1CX ≠ 0
LOOPE / LOOPZ hCX ← CX − 1CX ≠ 0 ve ZF = 1
LOOPNE / LOOPNZ hCX ← CX − 1CX ≠ 0 ve ZF = 0
JCXZ h(CX değişmez)CX = 0
Tuzak: CX = 0LOOP önce azaltır: 0 − 1 = FFFFh ≠ 0 → döngü 65 536 kez döner. Döngüden önce jcxz atla ile korunun.
BayraklarLOOP ailesi bayrakları değiştirmez; LOOPE/LOOPNE gövdedeki son CMP'nin ZF'sini okur. Hepsi kısa dallanmadır.
mov cx, n
jcxz bos       ; n = 0 ise hiç girme
tekrar: ; …gövde…
loop tekrar
bos:

Denetim Aktarma · Kodu adım adım çalıştır

Kod İzleme: LOOP ile Dizi Toplamı

BX = 0115h: dizinin ilk elemanının adresi.

CX = 5: LOOP sayacı.

Toplam AX = 0.

AX = AX + [BX] = 000Ah.

Sözcük (dw) dizisinde sonraki eleman 2 bayt ileride: BX = 0117h.

loop: CX = 0004h ≠ 0 → l1'e dön.

AX = AX + [BX] = 001Eh.

Sözcük (dw) dizisinde sonraki eleman 2 bayt ileride: BX = 0119h.

CX = 0003h → dön.

AX = AX + [BX] = 003Ch.

Sözcük (dw) dizisinde sonraki eleman 2 bayt ileride: BX = 011Bh.

CX = 0002h → dön.

AX = AX + [BX] = 0064h.

Sözcük (dw) dizisinde sonraki eleman 2 bayt ileride: BX = 011Dh.

CX = 0001h → dön.

AX = AX + [BX] = 0096h.

Sözcük (dw) dizisinde sonraki eleman 2 bayt ileride: BX = 011Fh.

CX = 0 → döngüden çık.

toplam = AX = 0096h = 150.

LOOP = dec cx + jnz, ama bayrakları etkilemez ve 2 bayttır.

org 100h
lea bx, dizi      ; BX → ilk eleman
mov cx, 5         ; eleman sayısı
mov ax, 0         ; toplam
l1:
add ax, [bx]      ; elemanı ekle
add bx, 2         ; sonraki sözcük
loop l1           ; CX--, ≠0 ise dön
mov toplam, ax
ret
dizi   dw 10, 20, 30, 40, 50
toplam dw 0

Denetim Aktarma

Alt Program Çağrısı: CALL ve RET

KomutYığına / yığındanSonra
CALL yakınpush IP (dönüş adresi)IP ← hedef
CALL uzakpush CS, push IPCS:IP ← hedef
RETpop IPçağıranın bir sonraki komutu
RETFpop IP, pop CSuzak dönüş
RET npop IP, SP ← SP + nyığındaki n baytlık parametreyi atar
  • Dönüş adresi, CALL'dan sonraki komutun adresidir.
  • Alt program içinde PUSH sayısı POP sayısına eşit olmalı; aksi hâlde RET yanlış adrese döner.
  • emu8086'da alt program ad PROC … ad ENDP ile tanımlanır (Bölüm 7: Prosedürler).

Denetim Aktarma · Kodu adım adım çalıştır

Kod İzleme: CALL / RET ve Dönüş Adresi

AL = 5.

call kare: sonraki komutun adresi (0105h) yığına atılır, SP = FFFCh, IP = kare (010Fh).

mul al: AX = 5 × 5 = 0019h (25).

ret: yığından 0105h çekilir → IP = 0105h, SP = FFFEh.

BL = 19h (25) saklanır.

AL = 7.

İkinci çağrı: dönüş adresi bu kez 010Ch.

AX = 7 × 7 = 0031h (49).

ret: IP = 010Ch, SP = FFFEh.

BL = 19h + 31h = 4Ah = 74.

Ana program biter.

org 100h
mov al, 5
call kare        ; yığına dönüş adresi
mov bl, al
mov al, 7
call kare
add bl, al       ; 25 + 49
ret
kare:
mul al           ; AX = AL × AL
ret              ; dönüş adresini çek

Denetim Aktarma

Yazılım Kesmesi: INT n

Kesme vektör tablosu (0000:xxxx)0080hINT 20h IP0082hINT 20h CS0084hINT 21h IP → 1460h0086hINT 21h CS → 0219h0088hINT 22h IPYığın (SS:SP)boşSP = FFFEhCS:IP0700:0110hIF = 1, TF = 0

Başlangıç: CS:IP = 0700:0110h → int 21h (CD 21) yürütülmek üzere. SP = FFFEh.

Kesme vektör tablosu (0000:xxxx)0080hINT 20h IP0082hINT 20h CS0084hINT 21h IP → 1460h0086hINT 21h CS → 0219h0088hINT 22h IPYığın (SS:SP)boşSP = FFFEhCS:IP0700:0110hIF = 1, TF = 0

Vektör adresi = 21h × 4 = 0084h. Kesme vektör tablosu 0000:0000–0000:03FFh arasındadır (256 × 4 bayt).

Kesme vektör tablosu (0000:xxxx)0080hINT 20h IP0082hINT 20h CS0084hINT 21h IP → 1460h0086hINT 21h CS → 0219h0088hINT 22h IPYığın (SS:SP)FFFChFLAGSSP = FFFChCS:IP0700:0110hIF = 0, TF = 0

FLAGS yığına atılır; ardından IF = 0, TF = 0 yapılır (kesme sırasında yeni maskelenebilir kesme ve tek adım kapalı).

Kesme vektör tablosu (0000:xxxx)0080hINT 20h IP0082hINT 20h CS0084hINT 21h IP → 1460h0086hINT 21h CS → 0219h0088hINT 22h IPYığın (SS:SP)FFFChFLAGSFFFAhCS = 0700hFFF8hIP = 0112hSP = FFF8hCS:IP0700:0110hIF = 0, TF = 0

CS ve dönüş IP'si (0112h, INT'ten sonraki komut) yığına atılır. SP = FFF8h.

Kesme vektör tablosu (0000:xxxx)0080hINT 20h IP0082hINT 20h CS0084hINT 21h IP → 1460h0086hINT 21h CS → 0219h0088hINT 22h IPYığın (SS:SP)FFFChFLAGSFFFAhCS = 0700hFFF8hIP = 0112hSP = FFF8hCS:IP0219:1460hIF = 0, TF = 0

IP ← [0000:0084h], CS ← [0000:0086h]. Yürütme kesme hizmet yordamında (ISR) devam eder.

Kesme vektör tablosu (0000:xxxx)0080hINT 20h IP0082hINT 20h CS0084hINT 21h IP → 1460h0086hINT 21h CS → 0219h0088hINT 22h IPYığın (SS:SP)boşSP = FFFEhCS:IP0700:0112hIF = 1, TF = 0

ISR iret ile biter: IP, CS ve FLAGS ters sırada geri alınır; program 0700:0112h'den sürer.

INT 3 tek baytlık (CCh) kesme noktası komutudur; INTO, OF = 1 ise INT 4 üretir. Tablodaki ISR adresi örnektir.

İşlemci Denetimi

İşlemci Denetimi Komutları

KomutEtki
CLC / STCCF ← 0 / CF ← 1
CMCCF ← ¬CF
CLD / STDDF ← 0 / 1 (dizgi yönü)
CLI / STIIF ← 0 / 1 (INTR kesmeleri)
KomutEtki
HLTkesme ya da RESET gelene kadar dur
WAITTEST̅ ucu etkinleşene kadar bekle (8087 eşlemesi)
ESCkomutu yardımcı işlemciye (8087) ilet
LOCKönek: sonraki komut süresince LOCK̅ ucu → yol kilitlenir
NOPhiçbir şey yapma (90h), 3 saat çevrimi
CLC/STCAlt programdan başarı/hata döndürmenin yaygın yolu: hata varsa stc, çağıran jc hata.
CLI/STIKritik bölgeyi (ör. SS:SP değiştirme) kesmelerden korur. NMI maskelenemez.
LOCKÇok işlemcili sistemde lock xchg ile atomik semafor kurulur.

Bayrak Etkileri

Bayrak Etkileri Tablosu: Hesaplama Komutları

KomutOFSFZFAFPFCF
ADD ADC SUB SBB CMP NEG******
CMPS SCAS******
INC DEC*****–
MUL IMUL*????*
DIV IDIV??????
DAA DAS?*****
AAA AAS???*?*
AAM AAD?**?*?
AND OR XOR TEST0**?*0
SHL SAL SHR SAR*¹**?**
ROL ROR RCL RCR*¹––––*

* sonuca göre değişir · 0 temizlenir · – değişmez · ? tanımsız (güvenilmez) · ¹ OF yalnızca kaydırma sayısı 1 iken tanımlı. DF, IF, TF bu komutlardan etkilenmez.

Bayrak Etkileri

Bayrak Etkileri Tablosu: Diğer Komutlar

KomutlarEtkilenen bayraklar
MOV XCHG LEA LDS LES XLAT PUSH POP IN OUT LAHF PUSHF CBW CWD NOThiçbiri
MOVS LODS STOS, REPhiçbiri
JMP Jcc LOOP LOOPE LOOPNE JCXZ CALL REThiçbiri (yalnızca okunur)
SAHFSF ZF AF PF CF ← AH
POPF, IRETtümü (yığından)
INT n, INTOIF ← 0, TF ← 0 (eski FLAGS yığında)
CLC STC CMCCF
CLD STDDF
CLI STIIF
Sık yapılan hata: cmp ile jcc arasına bayrak değiştiren bir komut (ör. inc, add) koymak. Araya yalnızca MOV, PUSH, LEA gibi bayrak etkilemeyen komutlar girebilir.

Özet

Özet

KodlamaKomut 1–6 bayt: opcode (D, W) + ModR/M + yer değiştirme + anlık veri; önekler başa eklenir.
Veri taşımaMOV, XCHG, PUSH/POP, XLAT, LEA/LDS/LES, IN/OUT bayrakları etkilemez; bellekten belleğe MOV yoktur.
AritmetikCF işaretsiz, OF işaretli taşma. MUL/DIV örtük AL/AX/DX kullanır; BCD için DAA…AAD.
Mantık / kaydırmaAND temizler, OR kurar, XOR tersler, TEST sınar. Kaydırma sayısı 1 ya da CL.
DizgiDS:SI → ES:DI, DF yönü, REP/REPE/REPNE ile CX kadar yineleme.
DenetimJA/JB işaretsiz, JG/JL işaretli; Jcc ve LOOP kısa; CALL/INT dönüş adresini yığına atar.

Özet

Alıştırmalar

  1. mov dx, [bp+di+8] komutunu kodlayın (opcode 100010, d = 1, w = 1).
  2. AL = 96h, BL = 70h iken add al, bl sonrası AL, CF, OF, SF, ZF ne olur?
  3. AX = 0FFFh iken shl ax, 1, rcl dx, 1 (DX = 0, CF = 0) sonrası DX:AX?
  4. AL = 'z' iken xor al, 20h ve ardından and al, 0DFh sonrası AL?
  5. CX = 0 iken loop içeren bir döngü kaç kez döner? Nasıl önlenir?
  6. AX = 0007h, BL = 02h için div bl ve AX = FFF9h için idiv bl sonuçları?
  7. Bir dizgideki boşlukları sayan kodu repne scasb ile yazın.
İpuçları / cevaplar
  1. MOD = 01, REG = 010 (DX), R/M = 011 ([BP+DI]) → 8B 53 08; segment SS.
  2. 96h + 70h = 106h → AL = 06h, CF = 1, OF = 0 (negatif + pozitif), SF = 0, ZF = 0.
  3. AX = 1FFEh, CF = 0 → DX = 0000h; DX:AX = 00001FFEh.
  4. 'z' (7Ah) → 5Ah ('Z') → 5Ah ('Z').
  5. 65 536 kez; döngüden önce jcxz.
  6. AL = 03h, AH = 01h; IDIV: −7 ÷ 2 → AL = FDh (−3), AH = FFh (−1).
  7. Her bulunuşta sayacı artırıp CX ≠ 0 ise repne scasb'ı yineleyin (DI kaldığı yerden devam eder).

Özet

Kaynaklar

  • Intel, The 8086 Family User's Manual, 1979 (Bölüm 2: komut kümesi, Bölüm 4: komut kodlama).
  • Barry B. Brey, The Intel Microprocessors, 8. baskı, Pearson, 2009.
  • Kip R. Irvine, Assembly Language for x86 Processors, 7. baskı, Pearson, 2014.
  • emu8086 yardım belgeleri: 8086 instructions ve 8086 assembler tutorial.

Son

Bölüm 10: Komut Kümesi
Sonraki bölüm: Bölüm 11: Kesme Fonksiyonları
1 / 1 Sercan KÜLCÜ, Tüm hakları saklıdır.