Bölüm 5.1: Kesmeler

Mikroişlemciler
Kesme kavramıKesme türleriVektör tablosuINT ve IRETİstisnalar: INT 0, 1, 3, 4Donanım kesmeleri8259A ve maskelemeKendi kesme yordamı
Sercan KÜLCÜ · Giresun Üniversitesi · Elektrik-Elektronik Mühendisliği

Giriş

Öğrenme Çıktıları

Kavram

Kesmenin ne olduğunu, yoklamadan (polling) farkını ve kesme türlerini açıklamak.

Mekanizma

Kesme vektör tablosunu kullanarak INT n ile hangi adrese gidileceğini hesaplamak.

Yığın

INT ve IRET sırasında FLAGS, CS ve IP'nin yığına nasıl yazılıp geri alındığını izlemek.

Donanım kesmeleri

INTR kabulünü ve 8259A ile maskelemeyi izlemek; kendi kesme yordamını kurup eski vektörü geri yüklemek.

Kesme Kavramı

Kesme Nedir?

  • Kesme (interrupt), işlemcinin o anki işini geçici olarak bırakıp özel bir yordamı çalıştırmasını sağlayan olaydır.
  • Çalıştırılan yordama kesme hizmet yordamı denir: ISR (interrupt service routine).
  • ISR bitince işlemci, kaldığı komuttan devam eder; ana program kesildiğini fark etmez.
  • Yazılım kesmeleri, programlamayı kolaylaştıran hazır hizmetlerdir: karakter yazdırmak için kod yazmak yerine bir kesme çağrılır.
  • Ekran, klavye, disk sürücüsü, bellek yönetimi gibi donanımlarla çalışan kesme işlevleri vardır.
  • Kesmeler donanım tarafından da tetiklenebilir (klavyeye basılması, zamanlayıcı).
Günlük hayattan

Kitap okurken telefon çalar: sayfa işaretlenir (dönüş adresini saklama), telefon açılır (ISR), konuşma bitince işaretli sayfadan okumaya devam edilir (IRET).

ana programana program (devam)ISRINT / istekIRETdönüş adresi yığında

Kesme Kavramı

Yoklama mı, Kesme mi?

Yoklama (polling)hazır?hazır?hazır?hazır?hazır?hazır?hazır?hazır?hazır?hazır?CPU sürekli aygıtı sorar; çoğu soru boşa gider, veri geç fark edilebilir.Kesme (interrupt)ana programISRana program (kaldığı yerden)aygıt: “veri hazır”IRET ile dönüş

Yoklama

  • Basit, ek donanım gerekmez.
  • CPU zamanı boşa harcanır.
  • Olay, sorgu aralığına bağlı olarak geç algılanır.

Kesme

  • CPU yalnızca olay olduğunda meşgul edilir.
  • Olaya hızlı tepki verilir.
  • Vektör tablosu, yığın ve ISR düzeni gerekir.

Kesme Kavramı

Kesme Türleri

Yazılım kesmesi

Program içindeki INT n komutuyla bilerek çağrılır. BIOS ve DOS hizmetleri bu yolla kullanılır. INT 3 (kesme noktası) ve INTO (OF=1 ise INT 4) de yazılım kesmesidir.

Donanım kesmesi

Dış aygıt bir pini sürer. INTR maskelenebilir (IF=0 iken dikkate alınmaz), NMI maskelenemez (ör. bellek eşlik hatası, güç kaybı).

İç kesme (istisna)

İşlemcinin kendisi üretir: sıfıra bölme / bölüm taşması → INT 0, TF=1 iken her komuttan sonra tek adım → INT 1.

TipKaynakAçıklama
00hiçBölme hatası (DIV/IDIV sıfıra bölme veya bölüm sığmıyor)
01hiçTek adım (TF = 1) — hata ayıklayıcılar kullanır
02hdonanımNMI pini (maskelenemez)
03hyazılımKesme noktası; tek baytlık INT 3 (CCh)
04hyazılımINTO: OF = 1 ise taşma kesmesi
05h–FFh—Intel 05h–1Fh'yi ayırmıştır; PC'de BIOS, DOS ve kullanıcı programları kullanır

Kesme Kavramı

Üç Kaynağın Karşılaştırması

Yazılım (INT n)Donanım (INTR / NMI)İç (istisna)
Tetikleyenprogramdaki komutdış aygıt, pinişlemcinin kendisi
Zamanlamaeş zamanlı: hep aynı yerdeeş zamansız: herhangi bir komuttan sonraeş zamanlı: hatalı komutta
Tip numarasıkomutun içindeINTR: 8259A, INTA ile; NMI: hep 2sabit: 0, 1
IF = 0 ikenyine çalışırINTR bekler, NMI çalışıryine çalışır
Tipik kullanımBIOS/DOS hizmeti, INT 3, INTOklavye, zamanlayıcı, diskbölme hatası, tek adım
Ortak yolTip numarası bir kez belirlendikten sonra üçü de aynı adımları izler: FLAGS, CS, IP yığına; IF = TF = 0; CS:IP ← vektör.
Fark nerede?Yalnızca tip numarasının nereden geldiği ve kesmenin ne zaman oluştuğu farklıdır.

CLI yalnızca INTR girişini kapatır; yazılım kesmeleri ve istisnalar IF'den etkilenmez.

Kesme Vektör Tablosu

Kesme Vektör Tablosu (IVT)

  • Belleğin en başındaki 1 KB: 00000h–003FFh.
  • 256 kesme tipinin her biri için 4 baytlık bir vektör (ISR'nin adresi) tutulur.
  • Düşük adresli sözcük IP (bağıl konum), yüksek adresli sözcük CS (kesim) değeridir; ikisi de little-endian.
  • Tip n için vektörün adresi: n × 4.
  • Vektörü değiştirmek, kesmeyi başka bir yordama yönlendirmek demektir.
adres (0000:…)+0, +1+2, +30000hIPCSINT 00h0004hIPCSINT 01h0008hIPCSINT 02h000ChIPCSINT 03h⋮0040hIP = F065hCS = F000hINT 10h⋮0084hIPCSINT 21h⋮03FChIPCSINT FFh256 giriş × 4 bayt = 1024 bayt (0000:0000 – 0000:03FF)

INT 10h vektörü için gösterilen F000:F065 değeri, orijinal IBM PC BIOS'undaki video yordamının adresidir (örnek).

Kesme Vektör Tablosu

Vektör Adresi Adım Adım

INT 10hkesme tipi n = 10h = 16

Program INT 10h komutunu çalıştırır. Tip numarası n = 10h (16).

10h × 4 = 40h16 × 4 = 64 → adres 0000:0040h

Vektör adresi n × 4: 10h × 4 = 40h. (Onaltılıkta ×4, iki bit sola kaydırmaktır.)

0040h65h0041hF0h0042h00h0043hF0h} IP = F065h} CS = F000h

Bu 4 bayt okunur: düşük sözcük IP = F065h, yüksek sözcük CS = F000h (little-endian: önce düşük bayt).

fiziksel adres = CS × 16 + IPF0000h + F065h = FF065h

Yığına dönüş bilgisi yazıldıktan sonra CS:IP = F000:F065 yüklenir; ISR, fiziksel FF065h adresinden çalışmaya başlar.

Kesme Vektör Tablosu

Demo: Vektör Hesaplayıcı

Bir kesme tipi (00h–FFh) girilince tablodaki konumu ve kesmenin bilinen görevi gösterilir.

Hesap her zaman aynıdır: adres = n × 4. IP bu adreste, CS ise n × 4 + 2 adresindedir.

INT ve IRET

INT n Nasıl Çalışır?

1. FLAGS yazmacı yığına itilir: SP ← SP − 2, [SS:SP] ← FLAGS.
2. IF = 0 ve TF = 0 yapılır: ISR başka maskelenebilir kesmelerle ve tek adımla kesilmez.
3. CS yığına itilir.
4. IP (INT'ten sonraki komutun adresi) yığına itilir.
5. IP ← [n×4], CS ← [n×4+2]: ISR başlar.
6. ISR sonunda IRET: IP, CS ve FLAGS sırasıyla yığından geri alınır, program kaldığı yerden sürer.
Yığına toplam 6 bayt (3 sözcük) yazılır. IF'nin eski değeri FLAGS ile birlikte saklandığı için IRET onu da geri yükler.

INT ve IRET

INT ve IRET: Yığın Adım Adım

yığın (SS = 0700h)FFF6hFFF8hFFFAhFFFChFFFEh← SPCS0700hIP0104hSPFFFEhFLAGSF202h

INT 10h 0700:0104'te. SP = FFFEh, FLAGS = F202h (IF = 1; 8086'da bit 1 ve 12–15. bitler hep 1'dir).

yığın (SS = 0700h)FFF6hFFF8hFFFAhFFFChF202h← SPFFFEhCS0700hIP0104hSPFFFChFLAGSF202h

FLAGS itilir: SP = FFFCh, [FFFCh] = F202h.

yığın (SS = 0700h)FFF6hFFF8hFFFAhFFFChF202h← SPFFFEhCS0700hIP0104hSPFFFChFLAGSF002h

IF = 0, TF = 0 → FLAGS = F002h. Eski değer yığında güvende.

yığın (SS = 0700h)FFF6hFFF8hFFFAh0700h← SPFFFChF202hFFFEhCS0700hIP0104hSPFFFAhFLAGSF002h

CS itilir: SP = FFFAh, [FFFAh] = 0700h.

yığın (SS = 0700h)FFF6hFFF8h0106h← SPFFFAh0700hFFFChF202hFFFEhCS0700hIP0104hSPFFF8hFLAGSF002h

Dönüş adresi itilir: INT 10h 2 bayt olduğu için 0106h. SP = FFF8h.

yığın (SS = 0700h)FFF6hFFF8h0106h← SPFFFAh0700hFFFChF202hFFFEhCSF000hIPF065hSPFFF8hFLAGSF002h

CS:IP ← vektör (F000:F065). ISR çalışır ve karakteri yazar.

yığın (SS = 0700h)FFF6hFFF8h0106hFFFAh0700hFFFChF202h← SPFFFEhCS0700hIP0106hSPFFFChFLAGSF002h

IRET: IP ← 0106h, CS ← 0700h (SP = FFFCh).

yığın (SS = 0700h)FFF6hFFF8h0106hFFFAh0700hFFFChF202hFFFEh← SPCS0700hIP0106hSPFFFEhFLAGSF202h

FLAGS ← F202h, SP = FFFEh. Program 0106h'den devam eder. (Yığındaki eski değerler silinmez, yalnızca SP geri çekilir.)

INT ve IRET

INT/IRET ile CALL/RET

CALL / RETINT n / IRET
Hedef adreskomutun içinde (etiket)vektör tablosundan (n × 4)
Yığına yazılanIP (yakın) veya CS + IP (uzak)FLAGS + CS + IP (6 bayt)
BayraklardeğişmezIF = 0, TF = 0 yapılır
DönüşRET: IP (ve CS) geri alınırIRET: IP, CS, FLAGS geri alınır
Komut boyu3 bayt (yakın CALL)2 bayt (INT 3: 1 bayt)
Kim çağırır?yalnız programprogram, işlemci (istisna) veya donanım
ISR'yi RET ile bitirmek hatadır: yakın RET yalnız IP'yi alır; CS ve FLAGS yığında kalır (SP 4 bayt kayar) ve IF eski hâline dönmez. ISR'ler daima IRET ile biter.

INT ve IRET · Kodu adım adım çalıştır

Kod İzleme: IRET Yerine RET

org 100h
mov ax, 0
mov es, ax
mov word ptr es:[61h*4], offset isr
mov word ptr es:[61h*4+2], cs
int 61h
hlt              ; SP = ?
isr:
ret              ; HATA!
yığın (SS = 0700h)FFF8FFFAFFFCFFFE0000h← SPCS:IP (sonraki)0700:0103SPFFFEhIF = 1FLAGS = F202h

AX = 0: IVT kesimi.

yığın (SS = 0700h)FFF8FFFAFFFCFFFE0000h← SPCS:IP (sonraki)0700:0105SPFFFEhIF = 1FLAGS = F202h

ES = 0000h.

yığın (SS = 0700h)FFF8FFFAFFFCFFFE0000h← SPCS:IP (sonraki)0700:010CSPFFFEhIF = 1FLAGS = F202h

Tip 61h vektörünün IP'si: [184h] = offset isr = 0114h.

yığın (SS = 0700h)FFF8FFFAFFFCFFFE0000h← SPCS:IP (sonraki)0700:0111SPFFFEhIF = 1FLAGS = F202h

CS: [186h] = 0700h. Vektör 0700:0114.

yığın (SS = 0700h)FFF80113h← SPFFFA0700hFFFCF202hFFFE0000hCS:IP (sonraki)0700:0114SPFFF8hIF = 0FLAGS = F002h

int 61h: yığına FLAGS (F202h), CS (0700h), IP (0113h) — 6 bayt; SP = FFF8h, IF = 0.

yığın (SS = 0700h)FFF8FFFA0700h← SPFFFCF202hFFFE0000hartık veri: CS, FLAGSCS:IP (sonraki)0700:0113SPFFFAhIF = 0FLAGS = F002h

ISR'deki yakın ret (IRET olmalıydı) yalnız IP'yi alır (0113h): CS ve FLAGS yığında kaldı. SP = FFFAh, beklenen FFFEh'den 4 bayt eksik; IF = 0 kaldı.

yığın (SS = 0700h)FFF8FFFA0700h← SPFFFCF202hFFFE0000hartık veri: CS, FLAGSCS:IP (sonraki)0700:0114SPFFFAhIF = 0FLAGS = F002h

hlt'e gelindi ama kesmeler kapalı (IF = 0) ve yığın kaymış: bu noktadan sonra bir ret 0700h'yi dönüş adresi sanırdı. ISR daima IRET ile biter.

RETF bile yetmez: IP ve CS alınır ama FLAGS (2 bayt) yığında kalır ve IF eski hâline dönmez.

INT ve IRET

İstisnalar: Bölme Hatası ve INTO

INT 0: bölme hatasıDIV ya da IDIV iki durumda INT 0 üretir: bölen 0 ise ya da bölüm hedefe sığmıyorsa. AX = 1000, DIV BL (BL = 2): bölüm 500, AL'ye (en çok 255) sığmaz → INT 0. Bölen sıfır olmasa da hata oluşur.
Dönüş adresi8086 yığına DIV'den sonraki komutun adresini iter; IRET programı bölmeyi atlayarak sürdürür. 80286 ve sonrasında ise hatalı komutun kendi adresi itilir (komut yeniden denenebilir).
INTOTek baytlık komut (CEh). OF = 1 ise INT 4'ü çağırır, OF = 0 ise hiçbir şey yapmaz. İşaretli toplama ya da çıkarmadan hemen sonra yazılır: ADD AL, BL · INTO.
DOS ne yapar?DOS, INT 0 vektörüne kendi yordamını koyar: "Divide overflow" yazıp programı sonlandırır. Program kendi yordamını kurarak bu davranışı değiştirebilir.

Bölmeden önce bölenin sıfır olmadığını ve bölümün sığacağını denetlemek (ör. 16 bitlik bölme için DX:AX kullanmak) INT 0'ı baştan önler.

INT ve IRET · Kodu adım adım çalıştır

Kod İzleme: Kendi INT 0 Yordamımız

org 100h
mov ax, 0
mov es, ax           ; ES = 0: IVT
mov word ptr es:[0*4], offset hata
mov word ptr es:[0*4+2], cs
mov ax, 100
mov bl, 0
div bl               ; INT 0!
mov dl, al           ; dönüş buraya
ret
hata:
mov ax, 0FFFFh       ; hata işareti
iret
IVT 0000:0000h (tip 00h)001000F0IPCSvektör = F000:1000hyığın (SS = 0700)FFF6····FFF8····FFFA····FFFC····FFFE0000← SPAX0000BL00DL00CS:IP0700:0103IF1

AX = 0: IVT kesimi.

IVT 0000:0000h (tip 00h)001000F0IPCSvektör = F000:1000hyığın (SS = 0700)FFF6····FFF8····FFFA····FFFC····FFFE0000← SPAX0000BL00DL00CS:IP0700:0105IF1

ES = 0000h: ES:[0] tip 0'ın vektörüdür (0 × 4 = 0).

IVT 0000:0000h (tip 00h)1B0100F0IPCSvektör = F000:011Bhyığın (SS = 0700)FFF6····FFF8····FFFA····FFFC····FFFE0000← SPAX0000BL00DL00CS:IP0700:010CIF1

Düşük sözcük (IP) = offset hata = 011Bh. Önceki vektör öykünücünün varsayılan yordamını gösteriyordu.

IVT 0000:0000h (tip 00h)1B010007IPCSvektör = 0700:011Bhyığın (SS = 0700)FFF6····FFF8····FFFA····FFFC····FFFE0000← SPAX0000BL00DL00CS:IP0700:0111IF1

Yüksek sözcük (CS) = 0700h. Tip 0 artık bizim yordamımıza gider.

IVT 0000:0000h (tip 00h)1B010007IPCSvektör = 0700:011Bhyığın (SS = 0700)FFF6····FFF8····FFFA····FFFC····FFFE0000← SPAX0064BL00DL00CS:IP0700:0114IF1

AX = 100 = 0064h: bölünen.

IVT 0000:0000h (tip 00h)1B010007IPCSvektör = 0700:011Bhyığın (SS = 0700)FFF6····FFF8····FFFA····FFFC····FFFE0000← SPAX0064BL00DL00CS:IP0700:0116IF1

BL = 0: bölen sıfır.

IVT 0000:0000h (tip 00h)1B010007IPCSvektör = 0700:011Bhyığın (SS = 0700)FFF6····FFF80118← SPFFFA0700FFFCF202FFFE0000AX0064BL00DL00CS:IP0700:011BIF0

div bl → INT 0. Yığına FLAGS, CS ve dönüş IP'si 0118h (DIV'den sonraki komut) itilir; SP = FFF8h, IF = 0.

IVT 0000:0000h (tip 00h)1B010007IPCSvektör = 0700:011Bhyığın (SS = 0700)FFF6····FFF80118← SPFFFA0700FFFCF202FFFE0000AXFFFFBL00DL00CS:IP0700:011EIF0

Yordam çalışıyor: AX = FFFFh, programa "sonuç geçersiz" işareti.

IVT 0000:0000h (tip 00h)1B010007IPCSvektör = 0700:011Bhyığın (SS = 0700)FFF6····FFF8····FFFA····FFFC····FFFE0000← SPAXFFFFBL00DL00CS:IP0700:0118IF1

iret: IP = 0118h, CS, FLAGS geri alınır; SP = FFFEh, IF = 1. DIV yeniden çalışmaz.

IVT 0000:0000h (tip 00h)1B010007IPCSvektör = 0700:011Bhyığın (SS = 0700)FFF6····FFF8····FFFA····FFFC····FFFE0000← SPAXFFFFBL00DLFFCS:IP0700:011AIF1

DL = AL = FFh: ana program hatayı işaretten anlar.

IVT 0000:0000h (tip 00h)1B010007IPCSvektör = 0700:011Bhyığın (SS = 0700)FFF6····FFF8····FFFA····FFFC····FFFE····AXFFFFBL00DLFFCS:IP0700:0000IF1

ret: program DOS'a döner.

Kısalık için eski vektör saklanmadı; gerçek bir programda çıkıştan önce geri yüklenir. Değerler emu8086 benzeri .COM yüklemesi (CS = 0700h) için.

INT ve IRET

Hata Ayıklayıcının Araçları: INT 1 ve INT 3

Tek adım (TF): TF = 1 iken her komuttan sonra işlemci INT 1 üretir. TF'yi doğrudan değiştiren komut yoktur; FLAGS yığın üzerinden düzenlenir:

PUSHF
POP  AX
OR   AH, 01h      ; bit 8 = TF
PUSH AX
POPF              ; TF = 1

INT 1 yordamı TF = 0 ile çalışır (INT, TF'yi temizler); kendi komutları adım adım kesilmez. IRET, yığındaki TF = 1'i geri yükler.

Kesme noktası (INT 3): tek baytlık özel kodlaması vardır: CCh. Hata ayıklayıcı:

  1. Durulacak komutun ilk baytını saklar, yerine CCh yazar.
  2. Program oraya gelince INT 3 çalışır; yazmaçlar gösterilir.
  3. Saklanan bayt geri yazılır, yığındaki dönüş IP'si 1 azaltılır.
  4. IRET ile komut baştan çalıştırılır.

Tek bayt olduğu için en kısa komutun yerine bile sığar; INT 03h yazılsa iki baytlık CD 03 olurdu.

emu8086'nın "single step" düğmesi aynı işi öykünücü içinde yapar; gerçek işlemcide DEBUG gibi araçlar INT 1 ve INT 3 vektörlerini kullanır.

Donanım Kesmeleri

INTR Kabul Süreci

1. Aygıt (ör. klavye) IRQ1 hattını etkinleştirir; 8259A INTR pinini 1 yapar.
2. 8086 o anki komutu bitirir; kesmeler komut ortasında kabul edilmez.
3. IF = 0 ise istek bekletilir. IF = 1 ise kabul edilir.
4. CPU iki INTA̅ darbesi üretir; ikinci darbede 8259A tip numarasını (PC'de klavye için 09h) veri yoluna koyar.
5. Bundan sonrası INT n ile aynıdır: FLAGS, CS, IP yığına; IF = TF = 0; CS:IP ← [n×4].
6. ISR işini bitirince 8259A'ya EOI (kesme sonu) gönderir ve IRET ile döner.
INTR = 11komut biter2IF = 1?3INTA̅ ×2 → 09h4yığına itilir5ISR … IRET6zaman

Donanım Kesmeleri

Öncelik ve PC Kesme Haritası

8086 öncelik sırası

SıraKaynak
1 (en yüksek)Bölme hatası, INT n, INTO
2NMI
3INTR
4 (en düşük)Tek adım (TF)

Aynı anda birden çok istek varsa, yüksek öncelikli olan önce hizmet görür.

IBM PC donanım kesmeleri

IRQAygıtTip
0Zamanlayıcı (18,2 Hz)08h
1Klavye09h
3 / 4Seri portlar0Bh / 0Ch
6Disket0Eh
7Yazıcı0Fh
Klavyeye basılınca önce donanım kesmesi INT 09h çalışır ve tuşu arabelleğe koyar; programın çağırdığı INT 16h bu arabellekten okur.

Donanım Kesmeleri

8259A İçinde Üç Yazmaç

IRQ0–7IRR (istek)IMR (maske)öncelik +ISR (hizmette)INTRport 21h: bit = 1 → o IRQ engelliEOI: port 20h ← 20hbekleyen isteklerINTA: 8259A tip numarasını (taban + IRQ no) veri yoluna koyar
IRRGelen ama henüz hizmet görmeyen istekleri tutar.
IMRKesme maske yazmacı: her IRQ için bir bit. IF tüm INTR'yi, IMR tek tek hatları kapatır.
ISR (yazmaç)O an hizmet gören IRQ'yu işaretler; EOI gelene kadar daha düşük öncelikliler bekler.

Bir ana 8259A'ya sekiz yardımcı bağlanarak 64 IRQ'ya çıkılır; PC/AT ikinci yongayı IRQ2'ye bağlar (IRQ8–15, tip 70h–77h). Yazmaç adı ISR, kesme hizmet yordamı ile karıştırılmamalıdır.

Donanım Kesmeleri · Kodu adım adım çalıştır

Kod İzleme: Tek Bir IRQ'yu Maskelemek

org 100h
in al, 21h           ; IMR'yi oku
or al, 00000010b     ; IRQ1 maskele
out 21h, al
mov cx, 3            ; kritik iş
in al, 21h
and al, 11111101b    ; IRQ1 aç
out 21h, al
ret
AL1IRQ70IRQ61IRQ51IRQ41IRQ30IRQ20IRQ10IRQ0B8hIMR10111000B8hzaman.klavyeCOM2COM1disketyazıcıkırmızı = maskeli (1) · port 21h = IMR

in al, 21h: IMR okunur, AL = B8h = 1011 1000b. IRQ3, 4, 5, 7 zaten maskeli (örnek değer).

AL1IRQ70IRQ61IRQ51IRQ41IRQ30IRQ21IRQ10IRQ0BAhIMR10111000B8hzaman.klavyeCOM2COM1disketyazıcıkırmızı = maskeli (1) · port 21h = IMR

or al, 02h: yalnızca bit 1 kurulur → AL = BAh. Diğer bitler korunur; IMR'ye henüz yazılmadı.

AL1IRQ70IRQ61IRQ51IRQ41IRQ30IRQ21IRQ10IRQ0BAhIMR10111010BAhzaman.klavyeCOM2COM1disketyazıcıkırmızı = maskeli (1) · port 21h = IMR

out 21h, al: IMR = BAh. IRQ1 (klavye) artık INTR'ye ulaşamaz; IF ve diğer IRQ'lar etkilenmedi.

AL1IRQ70IRQ61IRQ51IRQ41IRQ30IRQ21IRQ10IRQ0BAhIMR10111010BAhzaman.klavyeCOM2COM1disketyazıcıkırmızı = maskeli (1) · port 21h = IMR

Kesilmemesi gereken iş (burada yalnızca bir yer tutucu). Klavyeye basılırsa istek IRR'de bekler, kaybolmaz.

AL1IRQ70IRQ61IRQ51IRQ41IRQ30IRQ21IRQ10IRQ0BAhIMR10111010BAhzaman.klavyeCOM2COM1disketyazıcıkırmızı = maskeli (1) · port 21h = IMR

IMR yeniden okunur: AL = BAh.

AL1IRQ70IRQ61IRQ51IRQ41IRQ30IRQ20IRQ10IRQ0B8hIMR10111010BAhzaman.klavyeCOM2COM1disketyazıcıkırmızı = maskeli (1) · port 21h = IMR

and al, 0FDh (1111 1101b): yalnızca bit 1 silinir → AL = B8h.

AL1IRQ70IRQ61IRQ51IRQ41IRQ30IRQ20IRQ10IRQ0B8hIMR10111000B8hzaman.klavyeCOM2COM1disketyazıcıkırmızı = maskeli (1) · port 21h = IMR

out 21h, al: IMR = B8h, IRQ1 açıldı; bekleyen klavye isteği şimdi hizmet görür.

AL1IRQ70IRQ61IRQ51IRQ41IRQ30IRQ20IRQ10IRQ0B8hIMR10111000B8hzaman.klavyeCOM2COM1disketyazıcıkırmızı = maskeli (1) · port 21h = IMR

ret: maske ilk hâline döndü. Başkasının bitlerine dokunulmadı.

Oku–değiştir–yaz kalıbı: OR ile maskelenir, AND ile açılır, böylece diğer bitler korunur. CLI'den farkı: yalnızca seçilen aygıt bekletilir.

Donanım Kesmeleri

INTR Ne Zaman Kabul Edilmez?

Komut ortasındaİstek, yürüyen komut bitene kadar bekler. Önekler (LOCK, REP, kesim öneki) komutun parçası sayılır; önekle komut arasında kesme kabul edilmez.
SS yüklendikten ve STI'den sonraMOV SS, AX ya da POP SS'den sonraki komut da bitene kadar kesme gelmez: MOV SP, … güvenle tamamlanır. STI'den sonra da bir komut daha yürütülür; sti / hlt ya da sti / iret arasına kesme giremez.
REP'li dizgi komutuUzun bir REP MOVSB turlar arasında kesilebilir; dönüş adresi öneki gösterir, IRET'ten sonra kalan CX kadar sürer. 8086 yalnızca bir öneki hatırlar: REP ES: MOVSB kesilirse ES: öneki kaybolur, bu yüzden böyle bir satır CLI/STI arasına alınır.
HLT ve WAITHLT işlemciyi durdurur; bir INTR ya da NMI onu uyandırır ve IRET HLT'den sonraki komuta döner. WAIT sırasında gelen kesme de kabul edilir.

Kısacası 8086 kesmeyi yalnızca komut sınırlarında kabul eder; birkaç durumda bu sınır bilerek bir komut ileri kaydırılır.

Donanım Kesmeleri

Kesme Gecikmesi (Latency)

İşlem (8086)Saat turu
INT n51
INT 352
INTO (OF = 1 / OF = 0)53 / 4
INTR kabulü (iki INTA dahil)61
IRET24
16 bitlik IDIV (yazmaç)165–184

Kesme gecikmesi: isteğin gelmesiyle ISR'nin ilk komutunun başlaması arasındaki süre.

  • En kötü durumda önce yürüyen komut bitmelidir: uzun bir IDIV ≈ 184 tur.
  • Ardından kabul: 61 tur. Toplam ≈ 245 tur.
  • 5 MHz'de bir tur 200 ns → ≈ 49 µs.
  • CLI ile kapalı geçen süre bu gecikmeye doğrudan eklenir; CLI–STI arası kısa tutulur.

Saniyede 18,2 kez gelen zamanlayıcı kesmesi için bu süre önemsizdir; yüksek hızlı seri port gibi aygıtlarda ISR'nin kısa olması veri kaybını önler.

Donanım Kesmeleri

Kendi Kesme Yordamımız

org 100h
mov ax, 0
mov es, ax          ; ES = 0: IVT kesimi
cli                 ; kesmeleri kapat
mov word ptr es:[90h*4], offset isr  ; IP
mov word ptr es:[90h*4+2], cs       ; CS
sti                 ; kesmeleri aç
int 90h             ; kendi kesmemiz
ret
isr:
mov ah, 0Eh
mov al, '*'
int 10h
iret                ; RET değil!
  • Kullanılmayan bir tip seçilir: 90h. Vektörü 90h × 4 = 240h adresindedir.
  • IVT 0000 kesimindedir; ES = 0 yapılır.
  • Vektör yazılırken CLI/STI ile korunur: yarım yazılmış vektörle kesme gelmemelidir.
  • INT 90h ekrana * yazar ve program devam eder.
  • DOS altında INT 21h, AH = 25h (vektör ata) / 35h (vektör oku) daha güvenli yoldur.

Donanım Kesmeleri · Kodu adım adım çalıştır

Kod İzleme: INT 60h ile Kendi ISR'miz

org 100h
mov ax, 0
mov es, ax           ; ES = 0: IVT
cli
mov word ptr es:[60h*4], offset isr
mov word ptr es:[60h*4+2], cs
sti
mov al, '#'
int 60h              ; kendi kesmemiz
ret
isr:
mov ah, 0Eh
int 10h
iret
IVT 0000:0180h (tip 60h)????????IPCSyığın (SS = 0700h)FFF8FFFAFFFCFFFE0000h← SPCS:IP (sonraki)0700:0103FLAGSF202hIF = 1ekran:

AX = 0. Vektör tablosu (IVT) 0000:0000'dadır; tip 60h'nin vektörü 60h × 4 = 180h adresinde.

IVT 0000:0180h (tip 60h)????????IPCSyığın (SS = 0700h)FFF8FFFAFFFCFFFE0000h← SPCS:IP (sonraki)0700:0105FLAGSF202hIF = 1ekran:

ES = 0000h: ES:[180h] artık IVT'deki 0000:0180h baytını gösterir.

IVT 0000:0180h (tip 60h)????????IPCSyığın (SS = 0700h)FFF8FFFAFFFCFFFE0000h← SPCS:IP (sonraki)0700:0106FLAGSF002hIF = 0ekran:

cli: IF = 0. Vektör yarı yazılmışken donanım kesmesi gelmesin. FLAGS = F002h.

IVT 0000:0180h (tip 60h)1801????IPCSyığın (SS = 0700h)FFF8FFFAFFFCFFFE0000h← SPCS:IP (sonraki)0700:010DFLAGSF002hIF = 0ekran:

Düşük sözcük = IP = offset isr = 0118h: bellekte 18 01 (little-endian).

IVT 0000:0180h (tip 60h)18010007IPCSvektör = 0700:0118hyığın (SS = 0700h)FFF8FFFAFFFCFFFE0000h← SPCS:IP (sonraki)0700:0112FLAGSF002hIF = 0ekran:

Yüksek sözcük = CS = 0700h: 00 07. Vektör artık 0700:0118.

IVT 0000:0180h (tip 60h)18010007IPCSvektör = 0700:0118hyığın (SS = 0700h)FFF8FFFAFFFCFFFE0000h← SPCS:IP (sonraki)0700:0113FLAGSF202hIF = 1ekran:

sti: IF = 1, kesmeler yeniden açık. FLAGS = F202h (8086'da bit 1 ve 12–15. bitler hep 1).

IVT 0000:0180h (tip 60h)18010007IPCSvektör = 0700:0118hyığın (SS = 0700h)FFF8FFFAFFFCFFFE0000h← SPCS:IP (sonraki)0700:0115FLAGSF202hIF = 1ekran:

AL = '#' (23h): ISR'ye yazmaç ile iletilen parametre.

IVT 0000:0180h (tip 60h)18010007IPCSvektör = 0700:0118hyığın (SS = 0700h)FFF80117h← SPFFFA0700hFFFCF202hFFFE0000hCS:IP (sonraki)0700:0118FLAGSF002hIF = 0ekran:

int 60h: FLAGS (F202h), CS (0700h), dönüş IP'si (0117h) yığına; IF = 0; CS:IP ← [180h] = 0700:0118.

IVT 0000:0180h (tip 60h)18010007IPCSvektör = 0700:0118hyığın (SS = 0700h)FFF80117h← SPFFFA0700hFFFCF202hFFFE0000hCS:IP (sonraki)0700:011AFLAGSF002hIF = 0ekran: ISR içinde

ISR çalışıyor: AH = 0Eh (teletype).

IVT 0000:0180h (tip 60h)18010007IPCSvektör = 0700:0118hyığın (SS = 0700h)FFF80117h← SPFFFA0700hFFFCF202hFFFE0000hCS:IP (sonraki)0700:011CFLAGSF002hIF = 0ekran: #ISR içinde

int 10h: ekrana # yazılır. ISR içinden başka bir kesme çağrılabilir.

IVT 0000:0180h (tip 60h)18010007IPCSvektör = 0700:0118hyığın (SS = 0700h)FFF8FFFAFFFCFFFE0000h← SPCS:IP (sonraki)0700:0117FLAGSF202hIF = 1ekran: #ISR içinde

iret: IP = 0117h, CS = 0700h, FLAGS = F202h geri alınır; IF yeniden 1, SP = FFFEh.

IVT 0000:0180h (tip 60h)18010007IPCSvektör = 0700:0118hyığın (SS = 0700h)FFF8FFFAFFFCFFFECS:IP (sonraki)0700:0000FLAGSF202hIF = 1ekran: #

ret: ana program kaldığı yerden sürdü ve DOS'a döner.

Tip 60h kullanıcı programlarına ayrılmış tiplerdendir. Değerler emu8086 benzeri .COM yüklemesi (CS = 0700h) için.

Donanım Kesmeleri · Kodu adım adım çalıştır

Kod İzleme: Vektörü Sakla, Değiştir, Geri Yükle

org 100h
xor ax, ax
mov es, ax          ; ES = 0: IVT
mov ax, offset isr3
xchg ax, es:[3*4]   ; yeni IP ↔ eski
mov eski, ax
mov ax, cs
xchg ax, es:[3*4+2] ; yeni CS ↔ eski
mov eski+2, ax
mov ax, 1234h
int 3               ; bizim ISR
mov bx, eski
mov es:[3*4], bx    ; geri yükle
mov bx, eski+2
mov es:[3*4+2], bx
ret
isr3: push ax
mov ax, 0E21h       ; AH=0Eh, AL='!'
int 10h
pop ax
iret
eski dw ?, ?
IVT 0000:000Ch (tip 03h)031000F0IPCSvektör = F000:1003hyığın (SS = 0700)FFF6····FFF8····FFFA····FFFC····FFFE0000← SPAX0000BX0000CS:IP0700:0104IF1çıktı:

ES = 0000h: IVT. Tip 3'ün vektörü 3 × 4 = 000Ch adresinde.

IVT 0000:000Ch (tip 03h)031000F0IPCSvektör = F000:1003hyığın (SS = 0700)FFF6····FFF8····FFFA····FFFC····FFFE0000← SPAX0130BX0000CS:IP0700:0107IF1çıktı:

AX = offset isr3 = 0130h.

IVT 0000:000Ch (tip 03h)300100F0IPCSvektör = F000:0130hyığın (SS = 0700)FFF6····FFF8····FFFA····FFFC····FFFE0000← SPAX1003BX0000CS:IP0700:010CIF1çıktı:

xchg ax, es:[12]: tek komutta yeni IP yazılır, eski IP (1003h) AX'e gelir.

IVT 0000:000Ch (tip 03h)300100F0IPCSvektör = F000:0130hyığın (SS = 0700)FFF6····FFF8····FFFA····FFFC····FFFE0000← SPAX1003BX0000CS:IP0700:010FIF1çıktı:

Eski IP eski değişkenine saklandı.

IVT 0000:000Ch (tip 03h)300100F0IPCSvektör = F000:0130hyığın (SS = 0700)FFF6····FFF8····FFFA····FFFC····FFFE0000← SPAX0700BX0000CS:IP0700:0111IF1çıktı:

AX = CS = 0700h.

IVT 0000:000Ch (tip 03h)30010007IPCSvektör = 0700:0130hyığın (SS = 0700)FFF6····FFF8····FFFA····FFFC····FFFE0000← SPAXF000BX0000CS:IP0700:0116IF1çıktı:

xchg: yeni CS yazıldı, eski CS = F000h AX'te. Vektör artık 0700:0130.

IVT 0000:000Ch (tip 03h)30010007IPCSvektör = 0700:0130hyığın (SS = 0700)FFF6····FFF8····FFFA····FFFC····FFFE0000← SPAXF000BX0000CS:IP0700:0119IF1çıktı:

Eski CS de saklandı: eski vektör F000:1003. Tip 3'ü yalnızca program çağırdığı için CLI gerekmedi; donanım tiplerinde bu satırlar CLI/STI arasına alınır.

IVT 0000:000Ch (tip 03h)30010007IPCSvektör = 0700:0130hyığın (SS = 0700)FFF6····FFF8····FFFA····FFFC····FFFE0000← SPAX1234BX0000CS:IP0700:011CIF1çıktı:

AX = 1234h: ana programın değeri. ISR bunu bozmamalı.

IVT 0000:000Ch (tip 03h)30010007IPCSvektör = 0700:0130hyığın (SS = 0700)FFF6····FFF8011D← SPFFFA0700FFFCF246FFFE0000AX1234BX0000CS:IP0700:0130IF0çıktı:

int 3 (tek bayt, CCh): FLAGS, CS, dönüş IP'si 011Dh yığına; CS:IP ← 0700:0130.

IVT 0000:000Ch (tip 03h)30010007IPCSvektör = 0700:0130hyığın (SS = 0700)FFF61234← SPFFF8011DFFFA0700FFFCF246FFFE0000AX1234BX0000CS:IP0700:0131IF0çıktı:

push ax: ISR, kullanacağı AX'i önce saklar (1234h yığında).

IVT 0000:000Ch (tip 03h)30010007IPCSvektör = 0700:0130hyığın (SS = 0700)FFF61234← SPFFF8011DFFFA0700FFFCF246FFFE0000AX0E21BX0000CS:IP0700:0134IF0çıktı:

AX = 0E21h: AH = 0Eh (teletype), AL = 21h ('!').

IVT 0000:000Ch (tip 03h)30010007IPCSvektör = 0700:0130hyığın (SS = 0700)FFF61234← SPFFF8011DFFFA0700FFFCF246FFFE0000AX0E21BX0000CS:IP0700:0136IF0çıktı: !

int 10h: ekrana ! yazılır.

IVT 0000:000Ch (tip 03h)30010007IPCSvektör = 0700:0130hyığın (SS = 0700)FFF6····FFF8011D← SPFFFA0700FFFCF246FFFE0000AX1234BX0000CS:IP0700:0137IF0çıktı: !

pop ax: AX = 1234h, ana programın değeri geri geldi.

IVT 0000:000Ch (tip 03h)30010007IPCSvektör = 0700:0130hyığın (SS = 0700)FFF6····FFF8····FFFA····FFFC····FFFE0000← SPAX1234BX0000CS:IP0700:011DIF1çıktı: !

iret: IP, CS, FLAGS geri alınır; SP = FFFEh.

IVT 0000:000Ch (tip 03h)03100007IPCSvektör = 0700:1003hyığın (SS = 0700)FFF6····FFF8····FFFA····FFFC····FFFE0000← SPAX1234BX1003CS:IP0700:0126IF1çıktı: !

Eski IP vektöre geri yazıldı.

IVT 0000:000Ch (tip 03h)031000F0IPCSvektör = F000:1003hyığın (SS = 0700)FFF6····FFF8····FFFA····FFFC····FFFE0000← SPAX1234BXF000CS:IP0700:012FIF1çıktı: !

Eski CS de geri yazıldı: tip 3 yine eski yordamı gösteriyor.

IVT 0000:000Ch (tip 03h)031000F0IPCSvektör = F000:1003hyığın (SS = 0700)FFF6····FFF8····FFFA····FFFC····FFFE····AX1234BXF000CS:IP0700:0000IF1çıktı: !

ret: AX = 1234h korundu, vektör tablosu programdan önceki hâlinde.

Eski vektör F000:1003h öykünücünün varsayılan yordamıdır. DOS altında: INT 21h, AH = 35h / 25h.

Donanım Kesmeleri

ISR Yazım Kuralları ve Sık Yapılan Hatalar

KuralUyulmazsa
Kullanılan her yazmaç PUSH/POP ile korunur (FLAGS'i işlemci korur).Ana program, değeri kendiliğinden değişmiş bir yazmaçla devam eder; hata rastgele anlarda görülür.
Donanım ISR'si 8259A'ya EOI gönderir: MOV AL, 20h · OUT 20h, AL.8259A ISR bitini silmez; aynı ve daha düşük öncelikli IRQ'lar bir daha gelmez.
ISR kısa tutulur; uzun iş bir bayrak değişkeniyle ana programa bırakılır.Kesme gecikmesi büyür, hızlı aygıtların verisi kaybolur.
Donanım ISR'sinden INT 21h çağrılmaz.DOS yeniden girişli (reentrant) değildir; kesilen DOS çağrısının verileri bozulur.
Vektör CLI ile ya da AH = 25h ile yazılır, çıkışta eskisi geri yüklenir.Program bittikten sonra kesme, artık başka bir şeyin bulunduğu belleğe atlar.
ISR IRET ile biter.Yığın 4 bayt kayar, IF kapalı kalır.

Uzun bir ISR içinde STI ile daha öncelikli kesmelere izin verilebilir; bu durumda ISR'nin kendisi de yeniden girişli yazılmalıdır.

Laboratuvar · vektör tablosu, INT ve IRET adım adım

Laboratuvar: Kesme Mekanizması

Özet

Özet

Kesme

İşlemci işini bırakır, ISR'yi çalıştırır, IRET ile kaldığı yere döner.

Vektör tablosu

0000:0000–03FF, 256 × 4 bayt. Tip n → adres n × 4 (IP), n × 4 + 2 (CS).

INT n

FLAGS, CS, IP yığına (SP −6), IF = TF = 0, CS:IP ← vektör.

Donanım kesmesi

INTR yalnız IF = 1 iken, komut sınırında kabul edilir; tip numarası ikinci INTA darbesinde 8259A'dan gelir. NMI hep INT 2.

8259A

IMR tek tek IRQ'ları maskeler (port 21h); ISR sonunda EOI: MOV AL, 20h · OUT 20h, AL.

Kendi ISR

Vektör CLI/STI arasında yazılır, kullanılan yazmaçlar korunur, IRET ile biter; çıkışta eski vektör geri yüklenir.

Özet

Alıştırmalar

  1. INT 13h vektörü hangi fiziksel adreslerde bulunur?
  2. INT 21h çalışmadan önce SP = FFFEh ise ISR içindeyken SP kaçtır? Yığında ne vardır?
  3. IMR = B8h iken yalnız IRQ0'ı (zamanlayıcı) da maskeleyen komutları yazın. IMR kaç olur?
  4. Tip 61h'nin vektörü 0700:0120h yapılacak. Hangi fiziksel adreslere hangi baytlar yazılır?
  5. 5 MHz'lik 8086'da INTR geldiğinde MUL BX (en çok 133 tur) yeni başlamışsa kesme gecikmesi en çok ne kadardır?
  6. ISR'nin IRET yerine RET ile bitmesi ne gibi sorunlara yol açar?
İpuçları / cevaplar
  1. 13h × 4 = 4Ch → 0004Ch–0004Fh (IP: 4Ch–4Dh, CS: 4Eh–4Fh).
  2. SP = FFF8h. [FFF8h] = dönüş IP'si, [FFFAh] = CS, [FFFCh] = FLAGS.
  3. IN AL, 21h · OR AL, 01h · OUT 21h, AL → IMR = B9h; IRQ3, 4, 5, 7 maskeli kalır.
  4. 61h × 4 = 184h: 00184h–00187h ← 20 01 00 07 (önce IP, sonra CS; little-endian).
  5. 133 + 61 (INTR kabulü) = 194 tur × 200 ns ≈ 39 µs.
  6. CS ve FLAGS yığında kalır (yakın RET ile SP 4 bayt kayar), IF = 0 olarak kalır, ilk RET'te yanlış dönüş adresi alınabilir.

Özet

Kaynaklar

  • A. S. Tanenbaum, Modern Operating Systems, 3. baskı, Pearson, 2008.
  • Intel, The 8086 Family User's Manual, 1979 — Interrupts bölümü.
  • B. B. Brey, The Intel Microprocessors, 8. baskı, Pearson, 2009 — Bölüm 6 ve 12.
  • emu8086 yardım belgeleri: “Interrupts” ve “Supported interrupts” sayfaları.
  • R. Brown, Ralf Brown's Interrupt List (BIOS/DOS kesme başvurusu).

Son

Bölüm 5.1: Kesmeler
Sonraki bölüm: Bölüm 5.2: Kesme Fonksiyonları · Terim sözlüğü
1 / 1 Sercan KÜLCÜ, Tüm hakları saklıdır.