Bölüm 5: Kesme Fonksiyonları
Giriş
Öğrenme Çıktıları
BIOS ve DOS hizmetlerini AH'deki fonksiyon numarası ve yazmaç parametreleriyle çağırmak.
INT 10h ve INT 21h ile karakter, renkli karakter ve dizgi yazdırmak; imleci konumlamak.
INT 16h ve INT 21h ile tuş okumak, tuş beklemeden yoklamak, satır okumak.
Tarih/saat bilgisini okuyup yazdırmak; programı RET, INT 20h ya da INT 21h/4Ch ile doğru sonlandırmak.
Giriş
BIOS ve DOS Hizmetleri
- BIOS (Basic Input/Output System): anakarttaki ROM'da bulunan, donanımı doğrudan süren yordamlar. İşletim sistemi olmadan da çalışır; açılışta kesme vektör tablosunu doldurur.
- DOS: BIOS'un üstünde; dosya, dizgi, saat ve program yönetimi sunar. Kendi işi için çoğu zaman BIOS'u çağırır.
- Her iki katmana da yazılım kesmesi (
INT n) ile ulaşılır; çağıranın hizmet adresini bilmesi gerekmez.
Giriş
Hizmet Çağırma Kalıbı
- AH ← hizmet numarası (8 bit: en çok 256 hizmet)
- Diğer parametreler: AL, BX, CX, DX, DS:DX, ES:BP …
INT n(10h, 16h, 21h …)- 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
| Kesme | Sağlayan | Görev |
|---|---|---|
INT 10h | BIOS | video: mod, imleç, karakter, dizgi |
INT 16h | BIOS | klavye |
INT 1Ah | BIOS | saat sayacı, gerçek zaman saati |
INT 13h | BIOS | disk |
INT 20h | DOS | programı sonlandır (COM) |
INT 21h | DOS | yüzlerce hizmet: G/Ç, dosya, saat, çıkış |
Giriş
Ekran ve Klavyede ASCII
| Kod | Ad | Etki (0Eh / 02h) |
|---|---|---|
07h | BEL | zil sesi |
08h | BS | imleç bir geri |
09h | TAB | sekme (DOS) |
0Ah | LF | bir alt satır |
0Dh | CR | satır başı (Enter tuşu) |
1Bh | ESC | Esc tuşu |
| Karakter | ASCII | İlişki |
|---|---|---|
| boşluk | 20h | |
| '0' … '9' | 30h–39h | rakam = kod − 30h |
| 'A' … 'Z' | 41h–5Ah | bit 5 = 0 |
| 'a' … 'z' | 61h–7Ah | bit 5 = 1 (+20h) |
| '$' | 24h | 09h hizmetinde dizgi sonu |
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 Hizmetleri
| AH | Hizmet | Giriş | Çıkış / not |
|---|---|---|---|
00h | video modu seç | AL = mod (03h: 80×25 renkli metin) | ekran temizlenir |
01h | imleç şekli | CH = başlangıç, CL = bitiş satırı | CH = 20h → imleç gizli |
02h | imleç konumla | BH = sayfa, DH = satır, DL = sütun | |
03h | imleç konumu oku | BH = sayfa | DH, DL = konum; CH, CL = şekil |
06h | pencereyi yukarı kaydır | AL = satır (0 = temizle), BH = öznitelik, CH,CL – DH,DL = köşeler | ekran/pencere silme |
09h | karakter + öznitelik yaz | AL = karakter, BH = sayfa, BL = öznitelik, CX = sayı | imleç ilerlemez |
0Ah | yalnız karakter yaz | AL, BH, CX | mevcut öznitelik korunur |
0Eh | teletype çıkışı | AL = karakter, BH = sayfa | imleç ilerler; CR, LF, BS, BEL yorumlanır |
13h | dizgi yaz | AL = mod, BH, BL, CX = uzunluk, DH,DL, ES:BP = dizgi | AT ve sonrası BIOS |
INT 10h Video
AH = 00h: Video Modu ve Metin Ekranı
| AL | Mod | Bellek |
|---|---|---|
01h | 40×25 metin, 16 renk | B800h |
03h | 80×25 metin, 16 renk | B800h |
07h | 80×25 tek renk | B000h |
04h | 320×200, 4 renk | B800h |
13h | 320×200, 256 renk | A000h |
mov ah, 00h mov al, 03h ; ya da mov ax, 0003h int 10h ; temiz 80×25 ekran
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
INT 10h Video
Öznitelik (Attribute) Baytı
- Öznitelik = arka plan × 16 + ön plan.
07hvarsayılan (siyah üstüne açık gri),1Fhmavi üstüne beyaz,4Ehkı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?
| Özellik | AH = 09h | AH = 0Eh (teletype) |
|---|---|---|
| Girişler | AL = karakter, BH = sayfa, BL = öznitelik, CX = tekrar | AL = karakter, BH = sayfa |
| Renk | var (BL) | metin modunda yok (hücrenin rengi korunur) |
| İmleç | ilerlemez | ilerler, satır sonunda alt satıra geçer |
| CR, LF, BS, BEL | sembol olarak basılır (♪, ◘ …) | komut olarak yorumlanır |
| Ekran kaydırma | yok | son satırda ekran yukarı kayar |
| Tipik kullanım | renkli kutular, çerçeveler, aynı karakteri CX kez | düz metin akışı |
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.
09h imleci ilerletmez; yazdıktan sonra imleç AH = 02h ile ayrıca ilerletilir.
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
Demo: Metinden INT 10h Koduna
Yazılan metnin her karakteri için gereken MOV AL / INT 10h çifti ve ASCII kodları üretilir.
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ı |
|---|---|
AL | kaydırılacak satır sayısı; 0 = pencereyi temizle |
BH | boşalan satırların özniteliği |
CH, CL | sol üst köşe (satır, sütun) |
DH, DL | sağ 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
INT 10h Video · Kodu adım adım çalıştır
Ekranı ve Bir Pencereyi Temizlemek
org 100h mov ax, 0600h ; AH=06h, AL=0 mov bh, 1Fh ; mavi/beyaz mov cx, 0000h ; (0,0) mov dx, 184Fh ; (24,79) int 10h mov ax, 0600h mov bh, 4Fh ; kırmızı/beyaz mov cx, 0714h ; (7,20) mov dx, 103Bh ; (16,59) int 10h ret
AH = 06h (pencereyi yukarı kaydır), AL = 0: kaydırma yerine temizle.
BH = 1Fh: boşalan hücrelerin özniteliği (zemin 1 mavi, yazı F beyaz).
CX = 0000h → CH = 0 (satır), CL = 0 (sütun): sol üst köşe.
DX = 184Fh → DH = 18h = 24, DL = 4Fh = 79: sağ alt köşe.
INT 10h: 80 × 25 ekranın tamamı mavi zemine silinir. İmleç yerinde kalır.
İkinci çağrı: AX = 0600h, BH = 4Fh (kırmızı zemin, beyaz yazı).
CX = 0714h → (7, 20).
DX = 103Bh → (16, 59): 10 satır × 40 sütunluk kutu.
INT 10h: yalnız bu pencere kırmızıya silinir; dışı mavi kalır.
RET: program biter.
Yazmaç değerleri yorumlayıcıda çalıştırılarak alındı; yorumlayıcı 06h'nin ekran etkisini benzetmez, ekran BIOS tanımına göre çizildi.
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
INT 10h Video · Kodu adım adım çalıştır
Ekran Belleğine Doğrudan Yazmak
org 100h mov ax, 0B800h mov es, ax mov di, (1*80+4)*2 ; 00A8h mov ax, 4E41h mov es:[di], ax xor di, di mov ax, 072Eh mov cx, 3 ; ilk 3 hücre cld rep stosw ret
ES = B800h: mod 03h metin ekranının kesimi. Kesim yazmacına sabit doğrudan yazılamadığı için AX üzerinden.
(1, 4) hücresi: (1 × 80 + 4) × 2 = 168 = 00A8h. Çarpım derleme zamanında hesaplanır.
AX = 4E41h: AL = 41h ('A', karakter), AH = 4Eh (öznitelik: kırmızı zemin, sarı yazı).
MOV ES:[DI], AX: little-endian → B80A8h ← 41h, B80A9h ← 4Eh. Karakter anında ekranda; imleç yerinde kalır.
DI = 0: sol üst köşe.
AX = 072Eh ('.' + 07h açık gri), CX = 3.
CLD: DF = 0, DI artarak ilerler.
REP STOSW: ES:[DI] ← AX, DI += 2, CX kez → ilk 3 hücre '.' oldu; DI = 0006h, CX = 0. (Tüm ekran için CX = 2000.)
RET: program biter.
INT 10h Video
Mod 13h: 320×200, 256 Renk
mov ax, 0013h/int 10h: 320 × 200 grafik modu. Görüntü belleği A000:0000h – A000:F9FFh (64 000 bayt).- Her piksel 1 bayt: renk numarası (palet girişi). İlk 16 renk metin renkleriyle aynıdır: 0Eh sarı, 0Fh beyaz.
- Satır başına 320 = 140h bayt: bağıl konum = y · 320 + x.
- Örnek: (100, 50) → 50 · 320 + 100 = 16 100 = 3EE4h.
| INT 10h / AH = 0Ch: piksel yaz | |
|---|---|
AL | renk |
BH | sayfa (mod 13h'te 0) |
CX / DX | x (sütun 0–319) / y (satır 0–199) |
AH = 0Dh aynı CX, DX ile pikselin rengini AL'ye okur.
INT 10h Video
Köşegen Çizgi: BIOS ile ve A000h ile
INT 10h / 0Ch: koordinatla
mov ax, 0013h int 10h ; 320×200, 256 renk xor cx, cx ; x = 0 xor dx, dx ; y = 0 mov bh, 0 ; sayfa nokta: mov ax, 0C0Eh ; AH=0Ch, AL=sarı int 10h inc cx ; bir sağ inc dx ; bir alt cmp dx, 200 jb nokta ; 200 piksel
A000h belleği: bağıl konumla
mov ax, 0013h int 10h mov ax, 0A000h mov es, ax xor di, di ; (0,0) → ofset 0 mov al, 0Eh ; sarı mov cx, 200 ciz: mov es:[di], al add di, 141h ; 320 + 1 loop ciz mov ah, 0 int 16h ; tuş bekle mov ax, 0003h int 10h ; metin moduna dön
Belleğe doğrudan yazma, her piksel için kesme çağırmaktan çok daha hızlıdır.
emu8086'nın grafik desteği sınırlıdır: 0Ch yavaş çizer, A000h'a doğrudan yazma her sürümde görünmeyebilir; DOSBox'ta tam görünür.
INT 10h Video · Kodu adım adım çalıştır
Mod 13h Belleğine Köşegen Çizmek
org 100h mov ax, 0A000h mov es, ax xor di, di ; (0,0) → ofset 0 mov al, 0Eh ; sarı mov cx, 4 ; ilk 4 piksel ciz: mov es:[di], al add di, 141h ; 320 + 1 loop ciz ret
ES = A000h: mod 13h görüntü belleği (320 × 200, piksel başına 1 bayt).
DI = 0: (x, y) = (0, 0) piksel bağıl konumu y · 320 + x = 0.
AL = 0Eh (sarı), CX = 4: ilk 4 pikseli çiz.
ES:[0000h] ← 0Eh: piksel (0, 0). ADD DI, 141h → DI = 0141h (bir alt satır + bir sağ). LOOP: CX = 3.
ES:[0141h] ← 0Eh: piksel (1, 1). ADD DI, 141h → DI = 0282h (bir alt satır + bir sağ). LOOP: CX = 2.
ES:[0282h] ← 0Eh: piksel (2, 2). ADD DI, 141h → DI = 03C3h (bir alt satır + bir sağ). LOOP: CX = 1.
ES:[03C3h] ← 0Eh: piksel (3, 3). ADD DI, 141h → DI = 0504h (bir alt satır + bir sağ). LOOP: CX = 0. Döngü biter.
RET. 200 tur sürseydi son piksel (199, 199) = 199 · 321 = F987h olurdu.
INT 10h Video
Piksel Adresi Gezgini (320 × 200)
Ekrana tıklanınca (x, y) için y · 320 + x bağıl konumu ve fiziksel adres hesaplanır.
INT 16h Klavye
INT 16h: BIOS Klavye Hizmetleri
| AH | Hizmet | Çıkış |
|---|---|---|
00h | tuş bekle ve oku | AH = tarama kodu, AL = ASCII; tuş tampondan silinir |
01h | tuş var mı? (beklemez) | ZF = 1: yok · ZF = 0: AX = tuş, tampondan silinmez |
02h | Shift 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 / A | 1Eh | 61h / 41h |
| 1 | 02h | 31h |
| Enter | 1Ch | 0Dh |
| Esc | 01h | 1Bh |
| Boşluk | 39h | 20h |
| Tuş | AH (tarama) | AL |
|---|---|---|
| ↑ / ↓ | 48h / 50h | 00h |
| ← / → | 4Bh / 4Dh | 00h |
| F1 … F10 | 3Bh … 44h | 00h |
| Backspace | 0Eh | 08h |
| Ctrl+C | 2Eh | 03h |
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ş AH'den tanınır. Program sonundaki MOV AH, 0 · INT 16h çıktı ekranı kapanmadan okunabilsin diye bir tuş bekler.
INT 16h Klavye
Klavye Gezgini: INT 16h / AH = 00h Ne Döndürür?
Harfler, rakamlar, ok tuşları, F1–F10, Enter, Esc ve Ctrl+harf tanınır. 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 → atlama 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ıtma programda yapıldı.
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 Hizmetleri
| AH | Hizmet | Giriş | Çıkış |
|---|---|---|---|
01h | karakter oku, yansıt | – | AL = karakter |
02h | karakter yaz | DL = karakter | AL = DL |
07h / 08h | karakter oku, yansıtmadan | – | AL (08h Ctrl+C'yi denetler) |
09h | dizgi yaz | DS:DX → '$' ile biten dizgi | AL = 24h |
0Ah | tamponlu satır oku | DS:DX → tampon | tampon[1] = sayı, tampon+2 = metin |
2Ah | tarihi al | – | CX = yıl, DH = ay, DL = gün, AL = gün adı (0 = Pazar) |
2Ch | saati al | – | CH = saat, CL = dakika, DH = saniye, DL = salise |
2Bh / 2Dh | tarihi / saati ayarla | 2Ah / 2Ch ile aynı yazmaçlar | AL = 00h başarılı |
4Ch | programı sonlandır | AL = çıkış kodu | (dönmez) |
DOS hizmetleri G/Ç 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
INT 10h/0Eh mi, INT 21h/02h mi?
- Karakter AL'de.
- Doğrudan video BIOS'u; DOS gerekmez.
- Açılış (boot) kodunda da çalışır.
- Renk (grafik modda BL) verilebilir.
- Karakter DL'de.
- DOS çağrısı; çıktı yönlendirilebilir (dosyaya, yazıcıya).
- Dönüşte AL = DL olur.
- Ctrl+Break denetimi yapılır.
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 hizmetle 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
Program tamponu hazırlar: tampon db 10, ?, 10 dup(?). Bayt 0 = en fazla 10 karakter (Enter dahil).
Kullanıcı A yazar: karakter 2. konuma gelir ve ekrana yansıtılır. Backspace ile düzeltme yapılabilir.
l ve i de eklenir.
Enter: 0Dh sona yazılır; DOS bayt 1'e okunan sayıyı (3, CR hariç) yazar ve döner.
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) | |
|---|---|
CX | yıl (ör. 07EAh = 2026) |
DH | ay (1–12) |
DL | gün (1–31) |
AL | haftanın günü (0 = Pazar … 6 = Cumartesi) |
| AH = 2Ch (saat) | |
|---|---|
CH | saat (0–23) |
CL | dakika (0–59) |
DH | saniye (0–59) |
DL | salise (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$'
INT 21h DOS · Kodu adım adım çalıştır
Tablodan Gün Adı: AL × 4
org 100h 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$'
AH = 2Ah: DOS tarih hizmeti.
INT 21h dönüşte CX = yıl, DH = ay, DL = gün ve AL = haftanın günü verir. Örnek gün Çarşamba: AL = 3 (0 = Pazar).
AH = 0 (AX = 0003h), BL = 4: her gün adı '$' dahil 4 bayt.
MUL BL: AX = 3 × 4 = 12 = 000Ch: tablodaki bağıl konum.
DX = gunler = 0114h.
ADD DX, AX → DX = 0120h: 'Car$' dizgisinin başı.
AH = 09h, INT 21h: DS:DX'ten '$'a kadar → ekranda Car.
RET: program biter.
Yorumlayıcıda INT 21h/2Ah olmadığından çalıştırılan kopyada bu satır, aynı uzunluktaki mov al, 3 ile değiştirildi (örnek gün Çarşamba).
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.
Prosedür çağrılır: dönüş adresi yığında.
aam: 14 → AH = 1, AL = 4.
Her iki basamak ASCII'ye: AX = 3134h.
BX'te sakla; INT 21h/02h AL'yi değiştirir.
DL = onlar basamağı.
AH = 02h.
Ekrana '1'.
DL = birler basamağı.
Ekrana '4' → 14.
Prosedürden dönülür.
DL = ':'.
AH = 02h.
Ekrana ':'.
AL = dakika = 23h (35). CL hiçbir çağrıda bozulmadı.
Dakika için aynı prosedür.
35 → AH = 3, AL = 5.
Her iki basamak ASCII'ye: AX = 3335h.
BX'te sakla; INT 21h/02h AL'yi değiştirir.
DL = onlar basamağı.
AH = 02h.
Ekrana '3'.
DL = birler basamağı.
Ekrana '5' → 14:35.
Prosedürden 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
INT 1Ah ve BIOS Verileri
INT 1Ah: Saat Sayacı ve Gerçek Zaman Saati
| AH | İşlev | Dönüş |
|---|---|---|
00h | tık sayacını oku | CX:DX = gece yarısından beri tık, AL = gün döndü bayrağı |
02h | RTC saatini oku | CH = saat, CL = dakika, DH = saniye (BCD), DL = yaz saati; CF = 1: hata |
04h | RTC tarihini oku | CH = yüzyıl, CL = yıl, DH = ay, DL = gün (BCD); CF = 1: hata |
RTC, pille beslenen CMOS saatidir (AT ve sonrası); bilgisayar kapalıyken de çalışır.
Paketli BCD → ASCII (CL = 35h, yani dakika 35)
35h = 0011 0101b
Her 4 bit bir onluk basamaktır: yüksek nibble 3, düşük nibble 5.
shr dl, cl (CL = 4) → 03h
Üst basamak sağa kaydırılır. 8086'da 1'den büyük kaydırma sayısı CL ile verilir.
and dl, 0Fh → 05h
Alt basamak maskelenir.
+30h → '3' 33h, '5' 35h
Her basamak ASCII rakama çevrilir. INT 21h/2Ch ise aynı dakikayı ikili verir: CL = 23h; orada AAM gerekir.
INT 1Ah ve BIOS Verileri · Kodu adım adım çalıştır
Kod İzleme: RTC Saatini SS:DD:ss Yazdırma
AH = 02h: BIOS gerçek zaman saatini (RTC) oku.
Dönüş paketli BCD: CH = 14h (saat 14), CL = 35h (dakika 35), DH = 07h (saniye). DL = 00h (yaz saati yok).
CF = 0: okuma başarılı. CF = 1 olsaydı saat çalışmıyor demekti; program yazdırmadan biterdi.
CL'ye birazdan kaydırma sayısı yazılacak; dakika önce BL'ye kopyalanır.
CL = 4: SHR DL, CL 4 bit kaydıracak (8086'da 1'den büyük sabit kaydırma yok).
BH = saat = 14h. Prosedür değeri BH'de bekler; INT 21h/02h BH'yi bozmaz.
Saat için prosedür çağrılır (ikinokta atlanır, doğrudan bcdyaz).
DL = BH = 14h = 0001 0100b.
shr dl, cl: 0001 0100b → 0000 0001b. DL = 01h, yani üst basamak.
+30h: DL = 31h = '1'.
AH = 02h: DL'deki karakteri yaz.
Ekrana '1'. DOS, AL'ye DL'yi koyar (AL = 31h).
DL = BH = 14h (ikinci basamak için yeniden).
and dl, 0Fh: üst 4 bit silinir: 0000 0100b = 04h.
+30h: DL = 34h = '4'.
Ekrana '4' → 14. AH hâlâ 02h olduğundan yeniden yüklemek gerekmez.
Prosedürden dönülür.
BH = dakika = 35h (BL'de saklanmıştı).
Bu kez ikinokta girişi çağrılır: önce ':' yazar, sonra bcdyaz'a düşer.
DL = ':' (3Ah).
AH = 02h.
Ekrana ':' → 14:. Ardından komut bcdyaz etiketine kendiliğinden geçer (fall-through).
35h → 03h (üst basamak).
Ekrana '3' (33h).
35h AND 0Fh = 05h.
Ekrana '5' → 14:35.
Dönülür.
BH = saniye = 07h. DH, INT 21h/02h tarafından değiştirilmedi.
Saniye için yine ikinokta.
DL = ':'.
Ekrana ':' → 14:35:.
07h → 00h (üst basamak).
Ekrana '0' (30h).
07h AND 0Fh = 07h.
Ekrana '7' → 14:35:07.
Dönülür.
Ekranda 14:35:07. Aynı saat INT 21h/2Ch ile ikili (CH = 0Eh, CL = 23h) gelirdi; BCD'de onaltılık basamaklar doğrudan onluk basamaklardır.
org 100h mov ah, 02h int 1Ah ; CH=saat CL=dk DH=sn jc son ; CF=1: saat okunamadı mov bl, cl ; dakikayı sakla mov cl, 4 ; SHR kaydırma sayısı mov bh, ch call bcdyaz ; "14" mov bh, bl call ikinokta ; ":35" mov bh, dh call ikinokta ; ":07" son: ret ikinokta: mov dl, ':' mov ah, 02h int 21h bcdyaz: ; BH = paketli BCD mov dl, bh shr dl, cl ; üst hane add dl, 30h ; ASCII rakam mov ah, 02h int 21h mov dl, bh and dl, 0Fh ; alt hane add dl, 30h int 21h ret
INT 1Ah ve BIOS Verileri
BIOS Veri Alanı (Kesim 0040h)
| Adres | Boyut | İçerik |
|---|---|---|
0040:0010 | sözcük | donanım listesi (INT 11h'nin döndürdüğü değer) |
0040:0013 | sözcük | taban bellek, KB (INT 12h) |
0040:0017 | bayt | klavye bayrakları: bit 0 sağ Shift, 1 sol Shift, 2 Ctrl, 3 Alt, 4 Scroll Lock, 5 Num Lock, 6 Caps Lock, 7 Insert |
0040:001A | sözcük | tampon başı: sıradaki okunacak tuşun bağıl konumu |
0040:001C | sözcük | tampon sonu: sıradaki boş yerin bağıl konumu (baş = son → tampon boş) |
0040:001E–003D | 32 bayt | klavye tamponu: 16 sözcük (ASCII + tarama kodu), dairesel; en çok 15 tuş |
0040:0049 | bayt | geçerli video modu (03h, 13h, …) |
0040:004A | sözcük | ekrandaki sütun sayısı (mod 03h'te 80) |
0040:0050 | 8 sözcük | 8 sayfanın imleç konumu (düşük bayt sütun, yüksek bayt satır) |
0040:006C | dword | tık sayacı: gece yarısından beri ≈ 18,2 Hz'lik kesme sayısı |
0040:0070 | bayt | gece yarısı geçti bayrağı (INT 1Ah/00h AL'de verir ve sıfırlar) |
Fiziksel adres = 00400h + bağıl konum: 0040:006C = 0046Ch = 0000:046C. INT 16h ve INT 1Ah bu alanı kullanır; program da doğrudan okuyabilir.
INT 1Ah ve BIOS Verileri
BIOS Veri Alanını Okumak
; yaklaşık 1 saniye bekle mov ax, 0040h mov es, ax mov bx, es:[006Ch] ; başlangıç tıkı bekle: mov ax, es:[006Ch] ; şimdiki tık sub ax, bx ; geçen tık cmp ax, 18 ; 18 tık ≈ 0,99 s jb bekle ; Caps Lock açık mı? Bekleyen tuş var mı? test byte ptr es:[0017h], 40h jnz caps_acik ; bit 6 = 1 mov ax, es:[001Ah] ; tampon başı cmp ax, es:[001Ch] ; tampon sonu je tampon_bos
1 193 182 Hz ÷ 65 536 = 18,2065 Hz
8253/8254 zamanlayıcısı bölen 65 536 iken IRQ 0'ı bu sıklıkta üretir; her kesmede 0040:006C bir artar.
1 tık = 65 536 ÷ 1 193 182 s ≈ 54,9 ms
18 tık ≈ 0,989 s · 5 s ≈ 91 tık
Bekleme süresi tık sayısıyla ölçülür; çözünürlük yaklaşık 55 ms'dir.
Günde 1800B0h = 1 573 040 tık
Sayaç bu değere ulaşınca sıfırlanır ve 0040:0070 bayrağı kurulur.
sub ax, bx ile fark
Yalnız düşük sözcük okunur. Fark alındığı için düşük sözcük FFFFh → 0000h dönse de sonuç doğrudur; yalnız gece yarısındaki sıfırlama hesabı bozar.
Program Sonlandırma
Programı Sonlandırmanın Üç Yolu
| Yöntem | Nasıl çalışır? | Nerede? |
|---|---|---|
ret | COM 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 20h | DOS programı sonlandırır; CS'nin PSP kesimini göstermesi gerekir. | COM |
mov ax, 4C00hint 21h | AL'deki çıkış kodu ile sonlandırır, açık dosyaları kapatır. | COM ve EXE · önerilen |
IF ERRORLEVEL 1 ile sınanır.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).
- Dosya yalnız makine kodudur (başlık yok); yürütme 0100h'den başlar.
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
end basla ile belirtilir ve 64 KB'tan büyük olabilir. 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.Program Sonlandırma · Kodu adım adım çalıştır
EXE Programında DS Ayarı
.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 baslaBaşlangıçta DS = ES = 0700h: DOS onları PSP'ye ayarlar. CS = 0721h (kod), SS = 0710h (yığın). @data veri kesiminin değeridir → AX = 0720h.
MOV DS, AX: artık DS = 0720h, veri kesimini gösteriyor. Bu satır unutulsaydı DS:DX PSP'yi gösterir, ekrana çöp basılırdı.
DX = offset msg = 0000h: msg, veri kesiminin başında.
AH = 09h.
INT 21h: DS:DX = 0720h:0000h'den '$'a kadar → Merhaba.
AX = 4C00h, INT 21h: çıkış kodu 0 ile DOS'a dön. EXE'de RET kullanılamaz (yığının üstünde PSP adresi yok).
Kesim değerleri yorumlayıcının yerleşimidir (PSP 0700h); gerçek DOS'ta sayılar farklı olabilir, sıra ve DS ayarının gereği aynıdır.
Uygulama
Toplama, Çıkarma ve Sonucu Yazdırma
org 100h mov al, 5 ; bin=00000101b mov bl, 10 ; hex=0ah or bin=00001010b ; 5 + 10 = 15 (decimal), 0fh, 00001111b add bl, al ; 15 - 1 = 14 (decimal), 0eh, 00001110b sub bl, 1 mov cx, 8 ; sonucu ikilik tabanda yazdır
print: mov ah, 2 ; yazdırma fonksiyonu mov dl, '0' test bl, 10000000b ; ilk biti test et jz zero mov dl, '1' zero: int 21h shl bl, 1 loop print ; b (binary suffix) yazdır mov dl, 'b' int 21h ; klavye tuşu basılmasını bekle mov ah, 0 int 16h ret
- 5 + 10 − 1 = 14 = 0Eh hesaplanır; sonuç BL'dedir.
- Döngü 8 kez (CX = 8) çalışır: her turda BL'nin en anlamlı biti (MSB) test edilir, '0' ya da '1' yazılır, BL bir sola kaydırılır.
- En sonda 'b' eki yazılır ve bir tuşa basılması beklenir. Beklenen çıktı: 00001110b.
Uygulama
TEST ve SHL ile Bit Okuma
TEST BL, 10000000b: BL ile maske VE'lenir ama BL değişmez. Sonuç 0 ise bit 7 = 0 → ZF = 1, JZ atlar.
SHL BL, 1: tüm bitler bir sola kayar; çıkan bit 7 CF'ye gider, bit 0'a 0 girer. Bir sonraki bit, test edilecek konuma (bit 7) gelir.
8 tur sonunda BL'nin bitleri MSB'den LSB'ye sırayla yazılmış olur: 00001110, ardından b.
SHL BL,1 ardından JC ile CF'ye bakmak. Ancak bu sıralamada kaydırma, yazdırmadan önce yapılmalıdır.Uygulama · Kodu adım adım çalıştır
Kod İzleme (1/2): Hesaplama
AL = 5 = 05h = 00000101b. MOV bayrakları etkilemez.
BL = 10 = 0Ah = 00001010b.
ADD BL, AL: BL = 0Ah + 05h = 0Fh (15). Taşma yok (CF = 0), sonuçta dört 1 biti var → PF = 1.
SUB BL, 1: BL = 0Eh (14) = 00001110b. Üç 1 biti → PF = 0. Ödünç yok: CF = 0.
CX = 8: LOOP sayacı, her bit için bir tur.
org 100h mov al, 5 ; bin=00000101b mov bl, 10 ; hex=0ah or bin=00001010b ; 5 + 10 = 15 (decimal), 0fh, 00001111b add bl, al ; 15 - 1 = 14 (decimal), 0eh, 00001110b sub bl, 1 mov cx, 8 ; sonucu ikilik tabanda yazdır
Uygulama · Kodu adım adım çalıştır
Kod İzleme (2/2): İkili Yazdırma
Tur 1: AH = 2 (DOS karakter yaz).
Varsayılan karakter DL = '0' (30h).
TEST: bit 7 = 0 → ZF = 1, CF = 0.
ZF = 1 → JZ zero atlar; DL '0' kalır.
INT 21h: DL'deki '0' yazılır.
SHL BL,1: BL = 1Ch, çıkan bit CF = 0.
LOOP: CX = 7 ≠ 0 → print'e dön.
Tur 2 (özet): bit = 0, '0' yazıldı, BL = 38h. LOOP: CX = 6 ≠ 0 → print'e dön.
Tur 3 (özet): bit = 0, '0' yazıldı, BL = 70h. LOOP: CX = 5 ≠ 0 → print'e dön.
Tur 4 (özet): bit = 0, '0' yazıldı, BL = E0h. LOOP: CX = 4 ≠ 0 → print'e dön.
Tur 5: AH = 2 (DOS karakter yaz).
Varsayılan karakter DL = '0' (30h).
TEST: bit 7 = 1 → ZF = 0, CF = 0.
ZF = 0 → JZ atlamaz, sıradaki komut çalışır.
DL = '1' (31h).
INT 21h: DL'deki '1' yazılır.
SHL BL,1: BL = C0h, çıkan bit CF = 1.
LOOP: CX = 3 ≠ 0 → print'e dön.
Tur 6 (özet): bit = 1, '1' yazıldı, BL = 80h. LOOP: CX = 2 ≠ 0 → print'e dön.
Tur 7 (özet): bit = 1, '1' yazıldı, BL = 00h. LOOP: CX = 1 ≠ 0 → print'e dön.
Tur 8 (özet): bit = 0, '0' yazıldı, BL = 00h. LOOP: CX = 0 → döngü biter.
DL = 'b'. AH hâlâ 2.
INT 21h: 'b' eki yazılır.
AH = 0: tuş bekleme.
INT 16h: kullanıcı bir tuşa basana kadar beklenir (çıktı okunabilsin).
RET: program biter. Ekranda 00001110b.
print: mov ah, 2 ; yazdırma fonksiyonu mov dl, '0' test bl, 10000000b ; ilk biti test et jz zero mov dl, '1' zero: int 21h shl bl, 1 loop print ; b (binary suffix) yazdır mov dl, 'b' int 21h ; klavye tuşu basılmasını bekle mov ah, 0 int 16h ret
Uygulama
Ekran Çıktısı ve Notlar
emu8086 ekran penceresi (80×25)
- Sayının içi zaten ikilidir; yazdırmak, her biti '0'/'1' karakterine çevirmektir.
TESTsonucu saklamadığı için BL bozulmaz; bozan yalnızcaSHL'dir (bilerek).LOOPCX'i azaltır; döngü içinde CX başka amaçla kullanılmamalıdır.INT 21h/02hAL'yi değiştirir (AL = DL); AL'de saklanan bir değer varsa önce korunmalıdı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 → atlama 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
mov ax, @data / mov ds, ax.Özet
Özet: Hızlı Başvuru
| İş | Çağrı | Parametreler |
|---|---|---|
| Ekranı temizle | INT 10h / 00h | AL = 03h |
| İmleci konumla | INT 10h / 02h | BH = 0, DH = satır, DL = sütun |
| Renkli karakter | INT 10h / 09h | AL, BH, BL = öznitelik, CX = sayı |
| Karakter (daktilo) | INT 10h / 0Eh | AL |
| Renkli dizgi | INT 10h / 13h | AL = mod, BL, CX, DH:DL, ES:BP |
| Tuş bekle / yokla | INT 16h / 00h, 01h | → AH = tarama, AL = ASCII; 01h: ZF |
| Karakter oku / yaz | INT 21h / 01h, 02h | → AL / DL |
| Dizgi yaz / satır oku | INT 21h / 09h, 0Ah | DS:DX ('$' / tampon) |
| Tarih / saat | INT 21h / 2Ah, 2Ch | → CX DH DL AL / CH CL DH DL |
| RTC saati (BCD) | INT 1Ah / 02h | → CH CL DH, CF = 1 hata |
| Piksel (mod 13h) | INT 10h / 0Ch | AL = renk, CX = x, DX = y; ya da A000:(y·320 + x) |
| Programı bitir | INT 21h / 4Ch, INT 20h, RET | AL = çıkış kodu |
Özet
Alıştırmalar
- Ekranın tam ortasına (12, 38) mavi zemin üzerine beyaz "8086" yazan programı INT 10h/13h ile yazın.
- Kullanıcıdan iki rakam okuyup (01h) toplamlarını tek basamaklı olarak yazdırın (toplam ≤ 9).
- Esc'ye basılana kadar basılan tuşların tarama kodunu onaltılık yazdıran bir program yazın.
- 0Ah ile okunan metni tersten yazdırın.
- Tarihi GG.AA.YYYY biçiminde yazdırın. Yıl için hangi yöntemi kullanırsınız?
İpuçları / cevaplar
- AX = 1301h, BX = 001Fh, CX = 4, DX = 0C26h, ES:BP → '8086'.
- AL'den 30h çıkar, BL'de topla, sonra 30h ekleyip DL ile 02h; arada CR LF yazılır.
- INT 16h/00h; AH, XLAT tablosu ile iki onaltılık basamağa çevrilir;
cmp al, 1Bh. - SI = tampon+2+sayı−1'den geriye doğru:
std+lodsb+ 02h, CX = sayı. - Gün/ay için AAM; yıl (CX) için 10'a tekrarlı DIV ve yığın.
Özet
Alıştırmalar (devam)
mov ah, 09h/int 21hile '$' karakterini nasıl yazdırırsınız?- Mod 13h'te (160, 100) pikselinin A000h kesimindeki bağıl konumu nedir?
- INT 1Ah/02h DH = 59h döndürdü. Ekrana ne yazılır? Aynı saniye INT 21h/2Ch ile hangi değerle gelir?
- 0040:006C tık sayacıyla yaklaşık 5 saniye beklemek için kaç tık beklenmelidir?
İpuçları / cevaplar
- Yazdırılamaz; '$' için 02h hizmeti (DL = 24h) kullanılır.
- 100 · 320 + 160 = 32 160 = 7DA0h.
- '5' ve '9' → 59; 2Ch ise ikili DH = 3Bh verir.
- 5 × 18,2065 ≈ 91 tık.
Ö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.
- Ş. Ç. Öztürk, O. Ergin, Intel 8086 ile Mikroişlemci Programlamaya Giriş, 2009.