Bölüm 11: Kesme Fonksiyonları

Mikroişlemciler
BIOS ve DOSServis çağırmaINT 10h videoÖznitelik baytıINT 16h klavyeINT 21h karakter G/ÇDizgi ve satır girişiTarih ve saatProgram sonlandırma
Sercan KÜLCÜ · Giresun Üniversitesi · Elektrik-Elektronik Mühendisliği

Giriş

Öğrenme Çıktıları

Servis çağırma

BIOS ve DOS servislerini AH'deki fonksiyon numarası ve yazmaç parametreleriyle çağırmak.

Ekran çıktısı

INT 10h ve INT 21h ile karakter, renkli karakter ve dizgi yazdırmak; imleci konumlamak.

Klavye girişi

INT 16h ve INT 21h ile tuş okumak, tuş beklemeden yoklamak, satır okumak.

Saat ve sonlandırma

Tarih/saat bilgisini okuyup yazdırmak; programı RET, INT 20h ya da INT 21h/4Ch ile doğru sonlandırmak.

Giriş

BIOS ve DOS Servisleri

Uygulama programı (sizin kodunuz)mov ah, 09h / int 21hDOS hizmetleri: INT 20h, INT 21hdosya, dizgi, saat/tarih, program sonuBIOS hizmetleri: INT 10h, 13h, 16h, 1AhROM'daki aygıt yordamlarıDonanımekran kartı, klavye denetleyicisi, disk, saatdoğrudan porterişimi (IN/OUT)
  • BIOS (Basic Input/Output System): anakarttaki ROM'da bulunan, donanımı doğrudan süren yordamlar. İşletim sistemi olmadan da çalışır.
  • DOS: BIOS'un üstünde; dosya, dizgi, saat ve program yönetimi sunar.
  • Her iki katmana da yazılım kesmesi (INT n) ile ulaşılır; çağıranın servis adresini bilmesi gerekmez.
Aynı iş farklı katmanlarda yapılabilir: ekrana karakter INT 21h/02h (DOS), INT 10h/0Eh (BIOS) ya da doğrudan B800h ekran belleğine yazarak. Üst katman daha taşınabilir, alt katman daha hızlı ve esnektir.

Giriş

Servis Çağırma Kalıbı

  1. AH ← fonksiyon (servis) numarası
  2. Diğer parametreler: AL, BX, CX, DX, DS:DX, ES:BP …
  3. INT n (10h, 16h, 21h …)
  4. Sonuç yazmaçlarda: AL, AX, CX, DX, ZF/CF …
mov ah, 02h    ; servis: karakter yaz
mov dl, 'A'    ; parametre
int 21h        ; DOS'u çağır
KesmeSağlayanGörev
INT 10hBIOSvideo: mod, imleç, karakter, dizgi
INT 16hBIOSklavye
INT 1AhBIOSsaat sayacı, gerçek zaman saati
INT 13hBIOSdisk
INT 20hDOSprogramı sonlandır (COM)
INT 21hDOSyüzlerce servis: G/Ç, dosya, saat, çıkış
Servisler kendi kullandıkları yazmaçları değiştirebilir (ör. INT 21h/02h ve 09h AL'yi). Sonra gerekecek değerleri başka yazmaçta ya da yığında saklayın.

Giriş

Bir Servis Çağrısı Adım Adım: INT 21h

Kesme vektör tablosu0040hINT 10h → BIOS video0058hINT 16h → BIOS klavye0080hINT 20h → DOS0084hINT 21h → DOS (IP)0086hINT 21h → DOS (CS)YığınboşYürütülen yer0700:0105h

Çağrı öncesi: parametreler yazmaçlarda (AH = 09h, DX = msg). CS:IP = 0700:0105h, komut int 21h.

Kesme vektör tablosu0040hINT 10h → BIOS video0058hINT 16h → BIOS klavye0080hINT 20h → DOS0084hINT 21h → DOS (IP)0086hINT 21h → DOS (CS)YığınboşYürütülen yer0700:0105h21h × 4 = 0084h

İşlemci vektör adresini hesaplar: 21h × 4 = 84h → 0000:0084h.

Kesme vektör tablosu0040hINT 10h → BIOS video0058hINT 16h → BIOS klavye0080hINT 20h → DOS0084hINT 21h → DOS (IP)0086hINT 21h → DOS (CS)YığınFFFChFLAGSFFFAhCS = 0700hFFF8hIP = 0107hYürütülen yer0700:0105h

FLAGS, CS ve dönüş IP'si (0107h) yığına atılır; IF = TF = 0.

Kesme vektör tablosu0040hINT 10h → BIOS video0058hINT 16h → BIOS klavye0080hINT 20h → DOS0084hINT 21h → DOS (IP)0086hINT 21h → DOS (CS)YığınFFFChFLAGSFFFAhCS = 0700hFFF8hIP = 0107hYürütülen yerDOS: 09h servisi

CS:IP ← [0000:0086h]:[0000:0084h]. DOS'un INT 21h yordamı AH'ye bakarak 09h servisine dallanır.

Kesme vektör tablosu0040hINT 10h → BIOS video0058hINT 16h → BIOS klavye0080hINT 20h → DOS0084hINT 21h → DOS (IP)0086hINT 21h → DOS (CS)YığınboşYürütülen yer0700:0107h

Servis biter, iret ile IP, CS, FLAGS geri alınır. Sonuçlar yazmaçlarda (09h için AL = 24h).

Vektör tablosundaki adresler sistemden sisteme değişir; bu yüzden programlar servisleri adresle değil kesme numarasıyla çağırır. Ayrıntılar Bölüm 5: Kesmeler'de.

Giriş

Ekran ve Klavyede ASCII

KodAdEtki (0Eh / 02h)
07hBELzil sesi
08hBSimleç bir geri
09hTABsekme (DOS)
0AhLFbir alt satır
0DhCRsatır başı (Enter tuşu)
1BhESCEsc tuşu
KarakterASCIIİlişki
boşluk20h
'0' … '9'30h–39hrakam = kod − 30h
'A' … 'Z'41h–5Ahbit 5 = 0
'a' … 'z'61h–7Ahbit 5 = 1 (+20h)
'$'24h09h servisinde dizgi sonu
Yeni satır için iki karakter gerekir: 0Dh, 0Ah (CR LF). Yalnız LF imleci aşağı indirir ama satır başına getirmez. Türkçe harfler (ç, ğ, ı, ö, ş, ü) 7 bitlik ASCII'de yoktur; kod sayfasına (CP857) göre gösterilir.

INT 10h Video

INT 10h: BIOS Video Servisleri

AHServisGirişÇıkış / not
00hvideo modu seçAL = mod (03h: 80×25 renkli metin)ekran temizlenir
01himleç şekliCH = başlangıç, CL = bitiş satırıCH = 20h → imleç gizli
02himleç konumlaBH = sayfa, DH = satır, DL = sütun
03himleç konumu okuBH = sayfaDH, DL = konum; CH, CL = şekil
06hpencereyi yukarı kaydırAL = satır (0 = temizle), BH = öznitelik, CH,CL – DH,DL = köşelerekran/pencere silme
09hkarakter + öznitelik yazAL = karakter, BH = sayfa, BL = öznitelik, CX = sayıimleç ilerlemez
0Ahyalnız karakter yazAL, BH, CXmevcut öznitelik korunur
0Ehteletype çıkışıAL = karakter, BH = sayfaimleç ilerler; CR, LF, BS, BEL yorumlanır
13hdizgi yazAL = kip, BH, BL, CX = uzunluk, DH,DL, ES:BP = dizgiAT ve sonrası BIOS

INT 10h Video

AH = 00h: Video Modu ve Metin Ekranı

ALModBellek
01h40×25 metin, 16 renkB800h
03h80×25 metin, 16 renkB800h
07h80×25 tek renkB000h
04h320×200, 4 renkB800h
13h320×200, 256 renkA000h
mov ah, 00h
mov al, 03h   ; ya da mov ax, 0003h
int 10h      ; temiz 80×25 ekran
010203040506070790510152024(DH = 1, DL = 4)DL: sütun 0–79 →DHsatır0–24

emu8086 ekranı varsayılan olarak 80×25 metin modundadır; grafik modları sınırlı desteklenir.

INT 10h Video

İmleç Konumu: AH = 02h / 03h

  • Satır DH (0–24), sütun DL (0–79); sol üst köşe (0, 0).
  • BH = görüntü sayfası. 80×25 modda 8 sayfa (0–7) vardır; normalde 0 kullanılır.
  • İkisi tek komutla: mov dx, 0C28h → DH = 12, DL = 40 (ekranın ortası).
  • AH = 03h konumu okur: dönüşte DH, DL; ayrıca CH, CL imleç şekli.
  • INT 21h ile yazılan karakterler de bu imleç konumundan başlar.
; imleci ortaya al
mov ah, 02h
mov bh, 0
mov dx, 0C28h   ; 12. satır, 40. sütun
int 10h

; imleci bir sağa kaydır
mov ah, 03h
mov bh, 0
int 10h        ; DH, DL = konum
inc dl
mov ah, 02h
int 10h
Ekran belleği karşılığı: (satır, sütun) hücresinin bağıl konumu = (satır × 80 + sütun) × 2. Örneğin (1, 4) → 84 × 2 = 00A8h; çift adreste karakter, tek adreste öznitelik.

INT 10h Video

Öznitelik (Attribute) Baytı

B7R6G5B4I3R2G1B0yanıp sönmearka plan RGBparlakön plan RGBÖrnek: 1Eh = 0001 1110b → mavi zemin, sarı (parlak kahverengi) yazı
0 siyah1 mavi2 yeşil3 camgöbeği4 kırmızı5 eflatun6 kahve7 açık gri8 koyu gri9 açık maviA açık yeşilB açık camg.C açık kırmızıD açık eflatunE sarıF beyaz
  • Öznitelik = arka plan × 16 + ön plan. 07h varsayılan (siyah üstüne açık gri), 1Fh mavi üstüne beyaz, 4Eh kırmızı üstüne sarı.
  • Bit 7 = 1 ise karakter yanıp söner (ya da BIOS ayarına göre arka plan parlak olur): 8Fh.

INT 10h Video

Öznitelik Gezgini

Seçilen renklerden öznitelik baytı ve INT 10h/09h çağrısı üretilir.

INT 10h Video

Karakter Yazma: AH = 09h mı, 0Eh mi?

ÖzellikAH = 09hAH = 0Eh (teletype)
GirişlerAL = karakter, BH = sayfa, BL = öznitelik, CX = tekrarAL = karakter, BH = sayfa
Renkvar (BL)metin modunda yok (hücrenin rengi korunur)
İmleçilerlemezilerler, satır sonunda alt satıra geçer
CR, LF, BS, BELsembol olarak basılır (♪, ◘ …)komut olarak yorumlanır
Ekran kaydırmayokson satırda ekran yukarı kayar
Tipik kullanımrenkli kutular, çerçeveler, aynı karakteri CX kezdüz metin akışı
Renkli metin için yaygın kalıp: önce 09h ile karakteri renkli yaz (CX = 1), sonra imleci 02h ile bir sağa taşı; ya da tüm dizgi için 13h kullan.

INT 10h Video · Kodu adım adım çalıştır

Kod İzleme: Mod, İmleç, 09h ve 0Eh

AH = 00h (mod seç), AL = 03h (80×25, 16 renk metin). İki yazmaç tek komutla yüklenir.

int 10h: mod ayarlanır, ekran temizlenir, imleç (0,0)'a gider.

AH = 02h: imleç konumunu ayarla.

BH = görüntü sayfası (metin modunda 0–7; normalde 0).

DX = 0104h → DH = 1 (satır), DL = 4 (sütun). Sol üst köşe (0,0).

İmleç satır 1, sütun 4'e taşınır. Ekranda henüz bir şey yok.

AH = 09h: imleç konumuna AL'yi BL özniteliğiyle CX kez yaz.

Yazılacak karakter AL = '*' (2Ah).

BL = 4Eh: arka plan 4 (kırmızı), ön plan E (sarı).

Tekrar sayısı CX = 3.

Ekrana *** yazılır, ama 09h imleci ilerletmez: imleç hâlâ (1,4).

AH = 0Eh: teletype (daktilo) çıkışı.

AL = 'A'.

'A', imlecin bulunduğu (1,4)'e yazılır ve ilk yıldızın üzerine gelir; imleç (1,5)'e ilerler.

AL = 'B'. AH hâlâ 0Eh.

'B' (1,5)'e yazılır: ekranda AB*. 0Eh metin modunda öznitelik almaz; hücrelerdeki 4Eh rengi korunur.

Ders: 09h ile yazdıktan sonra imleci AH = 02h ile kendiniz ilerletmelisiniz.

org 100h
mov ax, 0003h    ; AH=00h, AL=03h
int 10h          ; ekran silinir
mov ah, 02h      ; imleç konumla
mov bh, 0        ; sayfa 0
mov dx, 0104h    ; DH=1, DL=4
int 10h
mov ah, 09h      ; karakter + öznitelik
mov al, '*'
mov bl, 4Eh      ; kırmızı üstüne sarı
mov cx, 3        ; 3 kez
int 10h          ; imleç ilerlemez!
mov ah, 0Eh      ; teletype
mov al, 'A'
int 10h          ; imleç ilerler
mov al, 'B'
int 10h
ret

INT 10h Video · Kodu adım adım çalıştır

Kod İzleme: AH = 13h ile Renkli Dizgi

AH = 13h (dizgi yaz). AL = 01h: tüm karakterler BL özniteliğinde, yazdıktan sonra imleç ilerler.

BH = 0 (sayfa), BL = 1Eh: mavi (1) zemin, sarı (E) yazı.

CX = karakter sayısı. '$' gibi bir bitiş işareti yoktur.

DH = 2, DL = 5: yazmanın başlayacağı konum.

Dizginin adresi ES:BP'de olmalıdır (DS:DX değil!). COM programında ES = DS: BP = 0113h.

Satır 2, sütun 5'ten itibaren Merhaba yazılır; imleç (2,12)'ye gider.

AL = 00h olsaydı dizgi yine yazılır ama imleç eski yerinde kalırdı. AL = 02h/03h'te dizgi karakter, öznitelik çiftlerinden oluşur.

org 100h
mov ax, 1301h    ; AH=13h, AL=01h
mov bx, 001Eh    ; BH=0, BL=1Eh
mov cx, 7        ; dizgi uzunluğu
mov dx, 0205h    ; satır 2, sütun 5
lea bp, mesaj    ; ES:BP → dizgi
int 10h
ret
mesaj db 'Merhaba'

INT 10h Video

AH = 06h: Pencere Kaydırma ve Ekran Temizleme

YazmaçAnlamı
ALkaydırılacak satır sayısı; 0 = pencereyi temizle
BHboşalan satırların özniteliği
CH, CLsol üst köşe (satır, sütun)
DH, DLsağ alt köşe (satır, sütun)
  • AH = 07h aynı işi aşağı doğru yapar.
  • İmleç yerinde kalır; temizledikten sonra 02h ile (0,0)'a alın.
; tüm ekranı mavi zemine temizle
mov ax, 0600h   ; AH=06h, AL=0
mov bh, 1Fh     ; mavi/beyaz
mov cx, 0000h   ; (0,0)
mov dx, 184Fh   ; (24,79)
int 10h

; ortada 10×40'lık kırmızı kutu
mov ax, 0600h
mov bh, 4Fh
mov cx, 0714h   ; (7,20)
mov dx, 103Bh   ; (16,59)
int 10h
184Fh = satır 24 (18h), sütun 79 (4Fh). Mod 03h'ü yeniden seçmek de ekranı temizler, ama renkleri varsayılana (07h) döndürür.

INT 10h Video

BIOS'suz Çıktı: B800h Ekran Belleği

  • Mod 03h'te ekran, B800:0000h'dan başlayan 4000 baytlık bellekte tutulur (80 × 25 × 2).
  • Her hücre 2 bayt: karakter (çift adres) + öznitelik (tek adres).
  • Belleğe yazılan değer ekran kartı tarafından anında gösterilir: kesme çağrısından çok daha hızlı.
  • Sözcük olarak yazarken little-endian: 4E41h → 41h ('A') düşük adrese, 4Eh özniteliğe.
; (1,4) hücresine sarı/kırmızı 'A'
mov ax, 0B800h
mov es, ax
mov di, (1*80+4)*2  ; 00A8h
mov ax, 4E41h
mov es:[di], ax

; tüm ekranı '.' ile doldur
xor di, di
mov ax, 072Eh
mov cx, 2000
cld
rep stosw
Doğrudan yazma imleci hareket ettirmez ve BIOS'un tuttuğu imleç bilgisini güncellemez. emu8086 bu belleği de destekler.

INT 16h Klavye

INT 16h: BIOS Klavye Servisleri

AHServisÇıkış
00htuş bekle ve okuAH = tarama kodu, AL = ASCII; tuş tampondan silinir
01htuş var mı? (beklemez)ZF = 1: yok · ZF = 0: AX = tuş, tampondan silinmez
02hShift durumlarıAL bitleri: 0 sağ Shift, 1 sol Shift, 2 Ctrl, 3 Alt, 4 Scroll, 5 Num, 6 Caps, 7 Insert
TuşAH (tarama)AL (ASCII)
a / A1Eh61h / 41h
102h31h
Enter1Ch0Dh
Esc01h1Bh
Boşluk39h20h
TuşAH (tarama)AL
↑ / ↓48h / 50h00h
← / →4Bh / 4Dh00h
F1 … F103Bh … 44h00h
Backspace0Eh08h
Ctrl+C2Eh03h

Tarama kodu tuşun klavyedeki fiziksel konumudur: 'a' ve 'A' aynı tarama kodunu verir. ASCII karşılığı olmayan (genişletilmiş) tuşlarda AL = 00h olur; tuşu AH'den tanırız.

INT 16h Klavye

Klavye Gezgini: INT 16h / AH = 00h Ne Döndürür?

AH (tarama kodu)--
AL (ASCII)--
AX----

Harfler, rakamlar, ok tuşları, F1–F10, Enter, Esc ve Ctrl+harf deneyin. Değerler IBM PC/AT klavye düzenine (US) göredir.

INT 16h Klavye · Kodu adım adım çalıştır

Kod İzleme: Enter'a Kadar Oku, Büyük Harfle Yaz

AH = 00h: klavye tamponundan bir tuş bekle ve al.

Kullanıcı O (Shift+o) bastı: AL = 4Fh (ASCII), AH = 18h (tarama kodu).

4Fh ≠ 0Dh.

Enter değil, devam.

'O' (4Fh) < 'a' (61h) → CF = 1.

Küçük harf değil → doğrudan yaz.

AH = 0Eh (teletype). AL'de yazılacak karakter var.

Ekrana O.

Sonraki tuşa dön.

AH = 00h: klavye tamponundan bir tuş bekle ve al.

Kullanıcı k bastı: AL = 6Bh, AH = 25h.

6Bh ≠ 0Dh.

Devam.

'k' ≥ 'a' → CF = 0.

Küçük harf olabilir, devam.

6Bh − 7Ah: ödünç → CF = 1, ZF = 0. Yani 'k' < 'z'.

ja CF = 0 ve ZF = 0 ister; CF = 1 → dallanma yok: küçük harf.

Bit 5 temizlenir: 6Bh − 20h = 4Bh = 'K'.

AH = 0Eh (teletype). AL'de yazılacak karakter var.

Ekrana K.

Sonraki tuşa dön.

AH = 00h: klavye tamponundan bir tuş bekle ve al.

Kullanıcı Enter bastı: AL = 0Dh, AH = 1Ch.

AL = 0Dh → ZF = 1.

Enter → bitti.

Enter'da program biter. INT 16h/00h tuşu ekrana yansıtmaz; yansıtmayı biz yaptık.

org 100h
oku:
mov ah, 0        ; tuş bekle
int 16h          ; AH=tarama, AL=ASCII
cmp al, 0Dh      ; Enter?
je bitti
cmp al, 'a'
jb yaz
cmp al, 'z'
ja yaz
sub al, 20h      ; küçük → büyük
yaz:
mov ah, 0Eh
int 10h          ; ekrana yaz
jmp oku
bitti:
ret

INT 16h Klavye · Kodu adım adım çalıştır

Kod İzleme: AH = 01h ile Beklemeden Yoklama

DX = 0: bekleme sırasında yapılan işi sayacağız.

Arka planda iş yapılıyor: DX = 0001h.

AH = 01h: tuş durumunu sorgula (beklemez).

Tamponda tuş yok → ZF = 1.

ZF = 1 → bekle'ye dön; program donmaz.

Arka planda iş yapılıyor: DX = 0002h.

AH = 01h: tuş durumunu sorgula (beklemez).

Hâlâ tuş yok → ZF = 1.

Yoklamaya devam.

Arka planda iş yapılıyor: DX = 0003h.

AH = 01h: tuş durumunu sorgula (beklemez).

Tuş geldi: ZF = 0, AL = 'x' (78h), AH = 2Dh. Tuş tamponda kalır.

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

Tuşu tampondan almak için AH = 00h.

Aynı tuş okunur ve tampondan silinir: AL = 'x', AH = 2Dh.

Oyunlarda ve animasyonlarda bu kalıp kullanılır: çalışmayı sürdür, tuşa basılınca tepki ver.

org 100h
xor dx, dx       ; iş sayacı
bekle:
inc dx           ; arka plan işi
mov ah, 01h      ; tuş var mı?
int 16h          ; ZF=1 → yok
jz bekle
mov ah, 00h      ; tuşu tampondan al
int 16h
ret

INT 21h DOS

INT 21h: Sık Kullanılan DOS Servisleri

AHServisGirişÇıkış
01hkarakter oku, yansıt–AL = karakter
02hkarakter yazDL = karakterAL = DL
07h / 08hkarakter oku, yansıtmadan–AL (08h Ctrl+C'yi denetler)
09hdizgi yazDS:DX → '$' ile biten dizgiAL = 24h
0Ahtamponlu satır okuDS:DX → tampontampon[1] = sayı, tampon+2 = metin
2Ahtarihi al–CX = yıl, DH = ay, DL = gün, AL = gün adı (0 = Pazar)
2Chsaati al–CH = saat, CL = dakika, DH = saniye, DL = salise
2Bh / 2Dhtarihi / saati ayarla2Ah / 2Ch ile aynı yazmaçlarAL = 00h başarılı
4Chprogramı sonlandırAL = çıkış kodu(dönmez)

DOS servisleri giriş/çıkış yönlendirmesine uyar: program > cikti.txt ile 02h/09h çıktısı dosyaya gider; BIOS INT 10h çıktısı ise her zaman ekrana gider.

INT 21h DOS · Kodu adım adım çalıştır

Kod İzleme: Karakter Oku, Yeni Satır, Karakter Yaz

AH = 01h: klavyeden bir karakter bekle ve ekrana yansıt.

Kullanıcı k bastı: AL = 6Bh, ekranda 'k' göründü.

AL sonraki INT 21h çağrılarında değişeceği için BL'de saklanır.

AH = 02h: DL'deki karakteri yaz.

DL = 0Dh (Carriage Return).

İmleç satır başına döner (görünür bir değişiklik yok).

DL = 0Ah (Line Feed).

İmleç bir alt satıra iner. Yeni satır = CR + LF.

BL = 6Bh + 1 = 6Ch = 'l'.

DL = 'l'.

Ekrana l yazılır. 02h sonrası AL de yazılan karakteri içerir.

Program biter.

org 100h
mov ah, 01h      ; oku + yansıt
int 21h          ; AL = karakter
mov bl, al       ; sakla
mov ah, 02h      ; karakter yaz
mov dl, 0Dh      ; CR: satır başı
int 21h
mov dl, 0Ah      ; LF: alt satır
int 21h
inc bl           ; sonraki harf
mov dl, bl
int 21h
ret

INT 21h DOS · Kodu adım adım çalıştır

Kod İzleme: AH = 09h ile Dizgi Yazdırma

DX = 010Dh: dizginin bağıl konumu. Kesim DS'dir.

AH = 09h: '$' ile biten dizgiyi yaz.

'$' görülene kadar yazılır; 0Dh 0Ah satırı bitirir. Dönüşte AL = 24h ('$').

İkinci dizgi: DX = 011Eh.

AH değişmediği için yeniden yüklemek gerekmez (yine de yüklemek iyi alışkanlıktır).

Çıktı iki satır. '$' karakterinin kendisi bu servisle yazdırılamaz.

org 100h
mov dx, offset msg1   ; DS:DX → dizgi
mov ah, 09h
int 21h
mov dx, offset msg2
int 21h               ; AH hâlâ 09h
ret
msg1 db 'Merhaba, 8086!', 0Dh, 0Ah, '$'
msg2 db 'Gule gule$'

INT 21h DOS

AH = 0Ah: Tamponlu Satır Girişi

0Ah+0?+1?+2?+3?+4?+5?+6en fazlaokunankarakterler …DS:DX →

Program tamponu hazırlar: tampon db 10, ?, 10 dup(?). Bayt 0 = en fazla 10 karakter (Enter dahil).

0Ah+0?+1'A'+2?+3?+4?+5?+6en fazlaokunankarakterler …DS:DX →

Kullanıcı A yazar: karakter 2. konuma gelir ve ekrana yansıtılır. Backspace ile düzeltme yapılabilir.

0Ah+0?+1'A'+2'l'+3'i'+4?+5?+6en fazlaokunankarakterler …DS:DX →

l ve i de eklenir.

0Ah+003h+1'A'+2'l'+3'i'+40Dh+5?+6en fazlaokunankarakterler …DS:DX →

Enter: 0Dh sona yazılır; DOS bayt 1'e okunan sayıyı (3, CR hariç) yazar ve döner.

0Ah+003h+1'A'+2'l'+3'i'+4'$'+5?+6en fazlaokunankarakterler …DS:DX →

Metin tampon+2'den başlar, uzunluğu [tampon+1]'dedir. '$' ile bitmez; 09h ile yazdırmak için 0Dh yerine '$' konur.

  • DOS satır düzenlemeyi kendisi yapar (Backspace, Esc); Enter'a basılana kadar program beklemez, çalışmaz.
  • Tampon dolunca fazla tuşlar kabul edilmez ve zil çalar. İlk bayt 0 olamaz.

INT 21h DOS · Kodu adım adım çalıştır

Kod İzleme: İsim Oku, Selam Ver

DS:DX tamponu gösterir: DX = 0120h.

AH = 0Ah: Enter'a kadar satır oku.

Kullanıcı Ali⏎ yazdı. DOS: tampon[1] = 3, tampon[2..4] = 'Ali', tampon[5] = 0Dh. Enter yalnızca CR basar: imleç satır başında.

BL = okunan karakter sayısı = 3 (CR sayılmaz).

BX = 0003h; adres hesaplamasında kullanılacak.

tampon[3 + 2] = tampon[5]: 0Dh yerine '$' yazılır → dizgi AH = 09h ile yazılabilir.

DX = selam.

AH = 09h.

CR LF + 'Merhaba ' yazılır (yeni satırda).

DX = tampon + 2: girilen metnin başlangıcı (0122h).

Çıktı: Merhaba Ali.

tampon[0] = 10: en çok 9 karakter + CR. Fazlası kabul edilmez (DOS zil sesi çalar).

org 100h
mov dx, offset tampon
mov ah, 0Ah          ; tamponlu giriş
int 21h
mov bl, [tampon+1]   ; okunan sayı
mov bh, 0
mov byte ptr tampon[bx+2], '$'
mov dx, offset selam
mov ah, 09h
int 21h
lea dx, [tampon+2]
int 21h
ret
tampon db 10, ?, 10 dup(?)
selam  db 0Dh, 0Ah, 'Merhaba $'

INT 21h DOS

AH = 2Ah / 2Ch: Tarih ve Saat

AH = 2Ah (tarih)
CXyıl (ör. 07EAh = 2026)
DHay (1–12)
DLgün (1–31)
ALhaftanın günü (0 = Pazar … 6 = Cumartesi)
AH = 2Ch (saat)
CHsaat (0–23)
CLdakika (0–59)
DHsaniye (0–59)
DLsalise (0–99)
; gün adını yazdır
mov ah, 2Ah
int 21h          ; AL = 0…6
mov ah, 0
mov bl, 4
mul bl           ; AX = AL × 4
mov dx, offset gunler
add dx, ax
mov ah, 09h
int 21h
ret
gunler db 'Paz$Pzt$Sal$Car$'
       db 'Per$Cum$Cmt$'
Değerler ikili sayıdır, BCD değil: saat 14 → CH = 0Eh. Ekrana yazmak için AAM ya da 10'a bölme kullanılır (sonraki slayt). BIOS'taki INT 1Ah/02h ise saati BCD olarak verir.

INT 21h DOS · Kodu adım adım çalıştır

Kod İzleme: Saati SS:DD Biçiminde Yazdırma

AH = 2Ch: sistem saatini oku.

Dönüş: CH = 14 (0Eh) saat, CL = 35 (23h) dakika, DH = 7 saniye, DL = 42 salise.

AL = saat = 0Eh.

Alt program çağrılır: dönüş adresi yığında.

aam: 14 → AH = 1, AL = 4.

Her iki hane ASCII'ye: AX = 3134h.

BX'te sakla; INT 21h/02h AL'yi değiştirir.

DL = onlar hanesi.

AH = 02h.

Ekrana '1'.

DL = birler hanesi.

Ekrana '4' → 14.

Alt programdan dönülür.

DL = ':'.

AH = 02h.

Ekrana ':'.

AL = dakika = 23h (35). CL hiçbir çağrıda bozulmadı.

Dakika için aynı alt program.

35 → AH = 3, AL = 5.

Her iki hane ASCII'ye: AX = 3335h.

BX'te sakla; INT 21h/02h AL'yi değiştirir.

DL = onlar hanesi.

AH = 02h.

Ekrana '3'.

DL = birler hanesi.

Ekrana '5' → 14:35.

Alt programdan dönülür.

Ekranda 14:35. Tarih için AH = 2Ah: CX = yıl, DH = ay, DL = gün, AL = haftanın günü.

org 100h
mov ah, 2Ch       ; sistem saatini al
int 21h           ; CH=saat CL=dakika
mov al, ch
call yaz2
mov dl, ':'
mov ah, 02h
int 21h
mov al, cl
call yaz2
ret
yaz2:             ; AL (0-99) → 2 hane
aam               ; AH=onlar AL=birler
add ax, 3030h     ; ASCII
mov bx, ax
mov dl, bh
mov ah, 02h
int 21h
mov dl, bl
int 21h
ret

Program Sonlandırma

Programı Sonlandırmanın Üç Yolu

YöntemNasıl çalışır?Nerede?
retCOM programında yığının üstünde 0000h vardır; RET, PSP:0000h'a döner, orada int 20h (CD 20) bulunur.yalnız COM, yığın dengeli ise
int 20hDOS programı sonlandırır; CS'nin PSP kesimini göstermesi gerekir.COM
mov ax, 4C00h
int 21h
AL'deki çıkış kodu ile sonlandırır, açık dosyaları kapatır.COM ve EXE · önerilen
Çıkış koduAL = 0 başarı, ≠ 0 hata anlamına gelir. Toplu iş dosyasında IF ERRORLEVEL 1 ile sınanır.
Sık hataSonlandırma komutu unutulursa işlemci programdan sonraki baytları (verileri!) komut gibi yürütür ve sistem kilitlenebilir.

PSP (Program Segment Prefix): DOS'un her programın önüne koyduğu 256 baytlık alan; COM'larda kod bu yüzden ORG 100h'tan başlar.

Program Sonlandırma

emu8086 Şablonları: COM ve EXE

COM (tek kesim)

org 100h
  mov dx, offset msg
  mov ah, 09h
  int 21h
  ret             ; ya da int 20h
msg db 'Merhaba$'
  • CS = DS = ES = SS; ayar gerekmez.
  • En fazla 64 KB (kod + veri + yığın).

EXE (ayrı kesimler)

.model small
.stack 100h
.data
msg db 'Merhaba$'
.code
basla:
  mov ax, @data
  mov ds, ax      ; DS'yi ayarla!
  mov dx, offset msg
  mov ah, 09h
  int 21h
  mov ax, 4C00h
  int 21h
end basla
EXE'de DOS başlangıçta DS'yi PSP'ye ayarlar; mov ax, @data / mov ds, ax yapılmazsa DS:DX yanlış yeri gösterir ve ekrana çöp basılır.

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

Kod İzleme: Mini Menü Programı

DX = menü metninin adresi.

AH = 09h.

Menü yazılır.

AH = 01h: yansıtmalı tek karakter oku.

Kullanıcı 1 bastı: AL = 31h (ekranda görünür).

31h ≠ 'q' → ZF = 0.

Çıkış değil.

AL = '1' → ZF = 1.

Eşit → dallanma yok (başka tuşta menü yeniden gösterilirdi).

DX = selam.

AH = 09h.

Yeni satıra Selam! yazılır.

Menüye dön.

DX = menü metninin adresi.

AH = 09h.

Menü yeniden yazılır.

AH = 01h: yansıtmalı tek karakter oku.

Kullanıcı q bastı: AL = 71h.

AL = 'q' → ZF = 1.

→ cikis.

AH = 4Ch (sonlandır), AL = 00h (çıkış kodu).

Program DOS'a döner; çıkış kodu toplu iş dosyalarında ERRORLEVEL ile okunur.

org 100h
goster:
mov dx, offset menu
mov ah, 09h
int 21h
mov ah, 01h       ; seçimi oku
int 21h
cmp al, 'q'
je cikis
cmp al, '1'
jne goster
mov dx, offset selam
mov ah, 09h
int 21h
jmp goster
cikis:
mov ax, 4C00h     ; çıkış kodu 0
int 21h
menu  db 0Dh, 0Ah, '1:Selam q:Cikis $'
selam db 0Dh, 0Ah, 'Selam!$'

Uygulama

Sık Yapılan Hatalar

'$' unutulduINT 21h/09h belleği '$' bulana kadar yazar: ekrana çöp dolar.
DS ayarlanmadı (EXE)DX doğru ama kesim yanlış: mov ax, @data / mov ds, ax.
AL'nin bozulması02h ve 09h AL'yi değiştirir; okunan karakteri yazmadan önce başka yazmaçta saklayın.
09h sonrası imleçINT 10h/09h imleci ilerletmez; sonraki yazı üstüne gelir.
13h'te DS:DXBIOS dizgi servisi adresi ES:BP'de bekler.
0Ah tamponuİlk bayt (kapasite) ayarlanmalı; metin tampon+2'den başlar, '$' ile bitmez.
Yalnız LFYeni satır için CR + LF (0Dh, 0Ah) gerekir.
Sonlandırma yokRET/4Ch unutulursa veriler komut olarak yürütülür.

Özet

Özet: Hızlı Başvuru

İşÇağrıParametreler
Ekranı temizleINT 10h / 00hAL = 03h
İmleci konumlaINT 10h / 02hBH = 0, DH = satır, DL = sütun
Renkli karakterINT 10h / 09hAL, BH, BL = öznitelik, CX = sayı
Karakter (daktilo)INT 10h / 0EhAL
Renkli dizgiINT 10h / 13hAL = kip, BL, CX, DH:DL, ES:BP
Tuş bekle / yoklaINT 16h / 00h, 01h→ AH = tarama, AL = ASCII; 01h: ZF
Karakter oku / yazINT 21h / 01h, 02h→ AL / DL
Dizgi yaz / satır okuINT 21h / 09h, 0AhDS:DX ('$' / tampon)
Tarih / saatINT 21h / 2Ah, 2Ch→ CX DH DL AL / CH CL DH DL
Programı bitirINT 21h / 4Ch, INT 20h, RETAL = çıkış kodu

Özet

Alıştırmalar

  1. Ekranın tam ortasına (12, 38) mavi zemin üzerine beyaz "8086" yazan programı INT 10h/13h ile yazın.
  2. Kullanıcıdan iki rakam okuyup (01h) toplamlarını tek haneli olarak yazdırın (toplam ≤ 9).
  3. Esc'ye basılana kadar basılan tuşların tarama kodunu onaltılı yazdıran bir program yazın.
  4. 0Ah ile okunan metni tersten yazdırın.
  5. Tarihi GG.AA.YYYY biçiminde yazdırın. Yıl için hangi yöntemi kullanırsınız?
  6. mov ah, 09h / int 21h ile '$' karakterini nasıl yazdırırsınız?
İpuçları / cevaplar
  1. AX = 1301h, BX = 001Fh, CX = 4, DX = 0C26h, ES:BP → '8086'.
  2. AL'den 30h çıkar, BL'de topla, sonra 30h ekleyip DL ile 02h; arada CR LF yazın.
  3. INT 16h/00h; AH'yi XLAT tablosu ile iki onaltılı haneye çevirin (Bölüm 10'daki örnek); cmp al, 1Bh.
  4. SI = tampon+2+sayı−1'den geriye doğru: std + lodsb + 02h, CX = sayı.
  5. Gün/ay için AAM; yıl (CX) için 10'a tekrarlı DIV ve yığın.
  6. Yazdırılamaz; '$' için 02h servisini (DL = 24h) kullanın.

Özet

Kaynaklar

  • Ralf Brown, Ralf Brown's Interrupt List (INT 10h, 16h, 21h ayrıntılı başvuru).
  • IBM, Personal Computer AT Technical Reference, BIOS bölümü, 1984.
  • Peter Abel, IBM PC Assembly Language and Programming, 5. baskı, Prentice Hall, 2001.
  • Barry B. Brey, The Intel Microprocessors, 8. baskı, Pearson, 2009.
  • emu8086 yardım belgeleri: supported interrupt functions.

Son

Bölüm 11: Kesme Fonksiyonları
Dersin sonu
1 / 1 Sercan KÜLCÜ, Tüm hakları saklıdır.