Bölüm 5: emu8086.inc Kütüphanesi
Çoktan Seçmeli · Kütüphane ve INCLUDE
Soru 1: INCLUDE Direktifi
include 'emu8086.inc' satırı için hangisi doğrudur?
B: INCLUDE bir direktiftir: assembler dosyanın içeriğini o noktaya metin olarak koyar, işlemci bu satırı hiç görmez (A yanlış). Makrolar kullanılmadan önce tanımlı olmalıdır; satır bu yüzden kaynağın başındadır (C yanlış). PUTC, PRINT gibi makrolar da kütüphanede tanımlıdır (D yanlış).
Çoktan Seçmeli · Kütüphane ve INCLUDE
Soru 2: Kütüphane Hakkında
emu8086.inc kütüphanesi için hangisi doğrudur?
D: PRINT_NUM işini yaparken PRINT_NUM_UNS'yi çağırır; ikincisi tanımlanmazsa derleyici etiketi bulamaz. PRINT, PRINTN, PUTC ve GOTOXY makrodur, doğrudan yazılır (A). GOTOXY sütun, satır sırasını kullanır (B). include satırı kaynağın başındadır (C).
Çıktı Sorusu · Makrolar
Soru 3: Makrolarla Ekran Çıktısı
Programın ekran çıktısı nedir? (b) İlk iki makro PRINTN 'A' ve PRINT 'B' olsaydı?
include 'emu8086.inc' ORG 100h PRINT 'A' PRINTN 'B' PUTC 'C' RET
Cevabı göster
Ekranda iki satır:
AB C
PRINT 'A' yalnızca A yazar; imleç aynı satırda kalır. PRINTN 'B' B'yi yazar, ardından 13 (CR) ve 10 (LF) ile imleci alt satırın başına götürür. PUTC 'C' C'yi oraya yazar.
(b) Satır sonu A'dan sonra gelir:
A BC
Çoktan Seçmeli · Makrolar
Soru 4: GOTOXY Neye Genişler?
GOTOXY 10, 5 makrosu INT 10h'yi çağırmadan önce yazmaçlara hangi değerleri koyar?
C: Makro sütun, satır sırasıyla yazılır; BIOS imleç konumlama hizmeti (AH = 02h) satırı DH'de, sütunu DL'de bekler. A sırayı ters çevirir; B'deki 0Eh karakter yazma (teletype) hizmetidir; D yanlış yazmaçları kullanır. Makro AX, BX ve DX'i yığında saklayıp geri yükler.
Adım Adım Çalıştırma · Makrolar
Soru 5: PUTC Yazmacı Bozar mı?
AX = 1234h iken PUTC 'A' kullanılıyor. Makronun açılımı çalışırken AX, SP ve yığın nasıl değişir? Makrodan sonra AX kaçtır?
Başlangıç: .COM programında SP = FFFEh; yığının üstünde DOS'un koyduğu 0000h var.
AX = 1234h. Makro bu değeri bozmamalı.
PUSH AX: SP = FFFCh, [FFFCh] = 1234h. Makro AX'i önce saklar.
MOV AL, 'A': AX = 1241h. Karakter AL'ye girer; AH henüz eski.
MOV AH, 0Eh: AX = 0E41h. 0Eh, BIOS'un karakter yazma (teletype) hizmetidir.
INT 10h: ekrana A yazılır, imleç bir sağa geçer.
POP AX: AX = 1234h, SP = FFFEh. Çağıran kod AX'in geçici olarak değiştiğini fark etmez.
ORG 100h MOV AX, 1234h ; PUTC 'A' şuna genişler: PUSH AX MOV AL, 'A' MOV AH, 0Eh INT 10h POP AX RET
Hesap Sorusu · Makrolar
Soru 6: İmleç Nerede?
Ekran boş, imleç (sütun 0, satır 0)'da. Her karakter hangi (sütun, satır) hücresine yazılır? Program bitince imleç nerededir?
include 'emu8086.inc' ORG 100h PRINT 'Hello World!' GOTOXY 10, 5 PUTC 65 PUTC 'B' PRINTN '!' PUTC 'C' RET
Cevabı göster
| Makro | Yazılan | Hücre (sütun, satır) |
|---|---|---|
| Hello World! | (0…11, 0) | |
| GOTOXY 10, 5 | — | imleç (10, 5) |
| PUTC 65 | A | (10, 5) |
| PUTC 'B' | B | (11, 5) |
| PRINTN '!' | ! + CR LF | (12, 5), imleç (0, 6) |
| PUTC 'C' | C | (0, 6) |
Son imleç: (1, 6). 65 = 41h = 'A'. GOTOXY yalnızca imleci taşır, ekrana bir şey yazmaz; CR imleci satır başına, LF bir alt satıra götürür.
Adım Adım Çalıştırma · Makrolar
Soru 7: PRINT 'Hi' Açılımı
PRINT 'Hi' makrosunun açılımı (AX = 1234h ile başlıyor). Dizgi nerede durur, SI nasıl ilerler, döngü nasıl biter?
Dizgi, makronun açıldığı yere, kodun içine gömüldü; sonuna 0 eklendi.
AX ve SI yığına saklandı. JMP, dizginin baytlarının üzerinden atlar; yoksa 48h, 69h komut sanılırdı.
SI = 0104h: dizginin ilk baytı.
AL = 'H' ≠ 0 (ZF = 0): SI ilerler, H yazılır.
AL = 'i' ≠ 0: SI = 0106h, i yazılır.
AL = 0 → ZF = 1, JZ bitti'ye atlar. Sondaki 0 dizginin bittiğini gösterir.
POP SI ve POP AX: iki yazmaç eski değerlerine döndü (AX = 1234h, SI = 0000h). Veri kod kesiminde olduğu için CS:[SI] kullanıldı.
ORG 100h ; PRINT 'Hi' şuna genişler: PUSH AX PUSH SI JMP atla s DB 'Hi', 0 atla: LEA SI, s sonraki: MOV AL, CS:[SI] CMP AL, 0 JZ bitti INC SI MOV AH, 0Eh INT 10h JMP sonraki bitti: POP SI POP AX RET
Çoktan Seçmeli · Prosedürler
Soru 8: PRINT mi, PRINT_STRING mi?
Bir programda 10 farklı dizgi yazdırılacak. PRINT makrosu 10 kez kullanılırsa ya da dizgiler PRINT_STRING ile yazdırılırsa karakter yazan döngü kodu kaç kez bulunur?
A: Makro her kullanıldığı yere açılır: 10 PRINT, dizgi ve döngü kodunun 10 kopyası demektir. Prosedür bir kez tanımlanır (DEFINE_PRINT_STRING); her dizgi için yalnızca LEA SI ve 3 baytlık CALL eklenir. Karşılığında prosedür her çağrıda CALL/RET süresi harcar.
Çoktan Seçmeli · Prosedürler
Soru 9: SCAN_NUM Sonucu
CALL scan_num çalışırken kullanıcı -25 yazıp Enter'a basıyor. Prosedür döndüğünde sonuç nerededir?
D: SCAN_NUM okuduğu işaretli sayıyı CX'te döndürür. −25, 16 bitte ikiye tümleyenle 65536 − 25 = 65511 = FFE7h olur. 8019h işaret-büyüklük gösterimi olurdu; 8086 bunu kullanmaz. Sayıyı PRINT_NUM ile yazmak için önce MOV AX, CX gerekir.
Çıktı Sorusu · Prosedürler
Soru 10: PRINT_NUM ve PRINT_NUM_UNS
AX'te aşağıdaki değerler varken CALL print_num ve CALL print_num_uns ekrana ne yazar?FFF6h · 8000h · 7FFFh · 0064h
Cevabı göster
| AX | print_num | print_num_uns |
|---|---|---|
| FFF6h | -10 | 65526 |
| 8000h | -32768 | 32768 |
| 7FFFh | 32767 | 32767 |
| 0064h | 100 | 100 |
Bitler aynıdır, yorum farklıdır. En anlamlı bit 1 ise işaretli değer = işaretsiz değer − 65536 (FFF6h: 65526 − 65536 = −10). MSB = 0 olan sayılarda iki prosedür aynı şeyi yazar.
Adım Adım Çalıştırma · Örnek Program
Soru 11: PTHIS Nasıl Döner?
PTHIS'in yazmaç saklayan kısımları çıkarılmış eşdeğeri. CALL yığına hangi adresi iter, prosedür onu nasıl kullanır, RET nereye döner?
CALL pthis 0100h'de (3 bayt). Hemen ardından 0103h'de dizginin baytları gelir.
CALL "sonraki komutun" adresini iter: [FFFCh] = 0103h. Bu adres aslında dizginin ilk baytıdır.
POP SI: dönüş adresi SI'ye alındı (SI = 0103h); yığın yeniden FFFEh'de.
Baytlar 0'a kadar yazılır: H, i. Her okumadan sonra SI bir artar.
AL = 0 okundu: SI = 0106h, yani 0 baytının bir ötesi. JE son'a atlar.
PUSH SI: yığına yeni "dönüş adresi" olarak 0106h konur.
RET IP'ye 0106h'yi aldı: dizgi atlandı, MOV BX, 1 çalıştı. Veri komut sanılıp yürütülmedi.
ORG 100h CALL pthis DB 'Hi', 0 MOV BX, 1 RET pthis PROC POP SI next: MOV AL, [SI] INC SI CMP AL, 0 JE son MOV AH, 0Eh INT 10h JMP next son: PUSH SI RET pthis ENDP
Çoktan Seçmeli · Örnek Program
Soru 12: DEFINE_ Yanlış Yerde
DEFINE_PTHIS satırı ORG 100h'nin hemen altına yazılırsa ne olur?
B: DEFINE_PTHIS, prosedürün kodunu bulunduğu yere açar. Orası programın başıysa işlemci 0100h'den itibaren PTHIS'e girer: yığından aldığı "dönüş adresi" DOS'un koyduğu 0000h'dır, PSP'deki baytları yazar ve oraya döner; çıktı anlamsızdır. Tanımların yeri RET ile END arasıdır.
Hata Bulma · Örnek Program
Soru 13: Üç Hata
Kullanıcıdan sayı alıp geri yazdıran programda üç hata var. Bulun ve düzeltin.
include 'emu8086.inc' ORG 100h DEFINE_PRINT_STRING LEA SI, msg CALL print_string CALL scan_num MOV AX, CX CALL print_num RET msg DB 'Sayi: ' DEFINE_SCAN_NUM DEFINE_PRINT_NUM END
Cevabı göster
- DEFINE_PRINT_STRING akışın içinde: işlemci program başında prosedür koduna girer. Tanımlar RET ile END arasına taşınır.
- msg 0 ile bitmiyor: PRINT_STRING 0 görene kadar yazar; ardındaki baytları da (prosedür kodları) ekrana döker.
msg DB 'Sayi: ', 0 - DEFINE_PRINT_NUM_UNS eksik: print_num onu çağırdığı için derleyici tanımsız etiket hatası verir.
... CALL print_num RET msg DB 'Sayi: ', 0 DEFINE_PRINT_STRING DEFINE_SCAN_NUM DEFINE_PRINT_NUM DEFINE_PRINT_NUM_UNS END
Kod Yazma · Örnek Program
Soru 14: İki Basamak Yazdırma
AX'te 0–99 arasında bir sayı var. Sayıyı iki onluk basamak olarak (7 → 07, 42 → 42) PUTC makrosuyla ekrana yazan kodu yazın.
Cevabı göster
MOV BL, 10 DIV BL ; AL = onlar, AH = birler ADD AX, 3030h ; iki basamak ASCII MOV BX, AX PUTC BL ; onlar basamağı PUTC BH ; birler basamağı
AX ≤ 99 olduğundan AH = 0'dır ve bölüm AL'ye sığar. 42 ÷ 10 → AL = 4, AH = 2; 3030h eklenince '4', '2'. Sonuç BX'e taşınır, çünkü PUTC karakteri AL'ye yükler ve AX'in eski içeriği basamakları bozardı.
Çoktan Seçmeli · CALL Komutu
Soru 15: Makro mu, Prosedür mü?
Makro ile prosedürü karşılaştıran ifadelerden hangisi doğrudur?
C: Makro derleme sırasında metin olarak açılır, bu yüzden çağrı maliyeti yoktur ama kodu her kullanımda büyütür. Prosedür bir kez bulunur, CALL ile çağrılır ve dönüş adresini yığına iter; A ile B rolleri karıştırır. Prosedürlere yazmaç, bellek ya da yığınla parametre verilir.
Hesap Sorusu · CALL Komutu
Soru 16: CALL Adım Adım
0110h adresindeki CALL print_num (3 bayt: E8 + 16 bitlik uzaklık) çalışacak; print_num 0200h'de, SP = FFFEh. (a) Komutun makine kodu nedir? (b) CALL'dan hemen sonra SP, [SP] ve IP kaçtır? (c) Prosedürün RET'inden sonra?
Cevabı göster
(a) Uzaklık, sonraki komuta göre: 0200h − 0113h = 00EDh → E8 ED 00 (little-endian: önce düşük bayt).
(b) SP = FFFCh, [FFFCh] = 0113h (dönüş adresi), IP = 0200h.
(c) RET: IP ← [FFFCh] = 0113h, SP = FFFEh. Ana program CALL'dan sonraki komutla sürer.
Prosedür kaç kez çağrılırsa çağrılsın gövdesi bir kez bulunur; her çağrı yalnızca bu 3 baytı ekler.