Bölüm 9: emu8086.inc Kütüphanesi

Bölüm 9: emu8086.inc Kütüphanesi · Çalışma Soruları
INCLUDEPUTC · GOTOXYPRINT · PRINTNMakro genişletmeDEFINE_ ve CALLSayı prosedürleriPTHISGET_STRING
Sercan KÜLCÜ

Ç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?

AX0000hSPFFFEhYığınFFFA····FFFC····FFFE0000h← SP

Başlangıç: .COM programında SP = FFFEh; yığının üstünde DOS'un koyduğu 0000h var.

AX1234hSPFFFEhYığınFFFA····FFFC····FFFE0000h← SP

AX = 1234h. Makro bu değeri bozmamalı.

AX1234hSPFFFChYığınFFFA····FFFC1234h← SPFFFE0000h

PUSH AX: SP = FFFCh, [FFFCh] = 1234h. Makro AX'i önce saklar.

AX1241hSPFFFChYığınFFFA····FFFC1234h← SPFFFE0000h

MOV AL, 'A': AX = 1241h. Karakter AL'ye girer; AH henüz eski.

AX0E41hSPFFFChYığınFFFA····FFFC1234h← SPFFFE0000h

MOV AH, 0Eh: AX = 0E41h. 0Eh, BIOS'un karakter yazma (teletype) hizmetidir.

AX0E41hSPFFFChYığınFFFA····FFFC1234h← SPFFFE0000h

INT 10h: ekrana A yazılır, imleç bir sağa geçer.

AX1234hSPFFFEhYığınFFFA····FFFC····FFFE0000h← SP

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
MakroYazılanHücre (sütun, satır)
PRINTHello World!(0…11, 0)
GOTOXY 10, 5—imleç (10, 5)
PUTC 65A(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.

Çoktan Seçmeli · Prosedürler

Soru 7: 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 8: 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 9: 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
AXprint_numprint_num_uns
FFF6h-1065526
8000h-3276832768
7FFFh3276732767
0064h100100

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.

Çoktan Seçmeli · Prosedürler

Soru 10: Tamponu Yazdırmak

GET_STRING ile doldurulan ad tamponu ekrana yazılacak. Hangisi doğrudur?

B: GET_STRING tamponu 0 ile bitirir; PRINT_STRING DS:SI'deki 0 ile biten dizgiyi yazar. AH = 09h '$' arar ve bulana kadar bellekteki baytları ekrana döker. PRINT yalnız kaynakta yazılan sabit metni koda gömer. PTHIS dizginin CALL'ın hemen ardında durmasını bekler; adresi yığındaki dönüş adresinden alır.

Hesap Sorusu · Prosedürler

Soru 11: GET_STRING Tampon Boyu

Kullanıcı Mehmetcan yazıp Enter'a basıyor. (a) Tampona kaç karakter alınır, baytlar nedir? (b) Aynı tamponla MOV DX, 10 verilseydi ne olurdu?

LEA DI, ad
MOV DX, 6
CALL get_string
...
ad   DB 6 DUP(0)
sayi DW 0
Cevabı göster

(a) En fazla DX − 1 = 5 karakter: 'M', 'e', 'h', 'm', 'e', 0. Tampon dolunca yeni harfler yok sayılır; prosedür Enter ya da geri silme bekler.

(b) Prosedür 9 karaktere kadar alır: tamponun 6 baytı yetmez, ardındaki sayi değişkeninin baytları ve sonrası ezilir. DX, tamponun gerçek boyundan büyük verilmemelidir.

Adım Adım Çalıştırma · Örnek Program

Soru 12: 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?

AX0000hSI0000hSPFFFEhCALL'dan sonraki baytlar'H'0103'i'010400h0105YığınFFFC····FFFE0000h← SP

CALL pthis 0100h'de (3 bayt). Hemen ardından 0103h'de dizginin baytları gelir.

AX0000hSI0000hSPFFFChCALL'dan sonraki baytlar'H'0103'i'010400h0105YığınFFFC0103h← SPFFFE0000h

CALL "sonraki komutun" adresini iter: [FFFCh] = 0103h. Bu adres aslında dizginin ilk baytıdır.

AX0000hSI0103hSPFFFEhCALL'dan sonraki baytlar'H'0103'i'010400h0105↑ SIYığınFFFC····FFFE0000h← SP

POP SI: dönüş adresi SI'ye alındı (SI = 0103h); yığın yeniden FFFEh'de.

AX0E69hSI0105hSPFFFEhCALL'dan sonraki baytlar'H'0103'i'010400h0105↑ SIYığınFFFC····FFFE0000h← SP

Baytlar 0'a kadar yazılır: H, i. Her okumadan sonra SI bir artar.

AX0E00hSI0106hSPFFFEhCALL'dan sonraki baytlar'H'0103'i'010400h0105YığınFFFC····FFFE0000h← SP

AL = 0 okundu: SI = 0106h, yani 0 baytının bir ötesi. JE son'a atlar.

AX0E00hSI0106hSPFFFChCALL'dan sonraki baytlar'H'0103'i'010400h0105YığınFFFC0106h← SPFFFE0000h

PUSH SI: yığına yeni "dönüş adresi" olarak 0106h konur.

AX0E00hSI0106hSPFFFEhCALL'dan sonraki baytlar'H'0103'i'010400h0105YığınFFFC····FFFE0000h← SP

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 13: DEFINE_ Yanlış Yerde

DEFINE_PTHIS satırı ORG 100h'nin hemen altına yazılırsa ne olur?

C: DEFINE_PTHIS prosedürün kodunu bulunduğu yere açar, ama emu8086.inc'teki her DEFINE_ makrosu JMP skip_proc_… ile başlar: işlemci prosedür gövdesinin üstünden atlar ve ana programa devam eder. Bu koruma olmasaydı B'deki durum yaşanırdı. Yine de alışılmış yer RET ile END arasıdır; programın başında her tanım fazladan bir JMP demektir.

Hata Bulma · Örnek Program

Soru 14: Üç 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 15: İ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'. Sonucun BX'e taşınması okunurluk içindir: PUTC makrosu AX'i PUSH/POP ile korur, bu yüzden PUTC AL ve PUTC AH da aynı sonucu verir.

Son

Bölüm 9: emu8086.inc Kütüphanesi: Çalışma Soruları
Konu anlatımı: emu8086.inc kütüphanesi sunumu · Terim sözlüğü
1 / 1 Sercan KÜLCÜ, Tüm hakları saklıdır.