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

Bölüm 5: emu8086.inc Kütüphanesi · Çalışma Soruları
INCLUDEPUTC · GOTOXYPRINT · PRINTNMakro genişletmeDEFINE_ ve CALLSayı prosedürleriPTHISCALL ve RETMakro mu, prosedür mü?
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.

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?

AX1234hSI0000hSPFFFEhZF0Kod içindeki dizgi (CS:0104h)'H'0104'i'010500h0106

Dizgi, makronun açıldığı yere, kodun içine gömüldü; sonuna 0 eklendi.

AX1234hSI0000hSPFFFAhZF0Kod içindeki dizgi (CS:0104h)'H'0104'i'010500h0106

AX ve SI yığına saklandı. JMP, dizginin baytlarının üzerinden atlar; yoksa 48h, 69h komut sanılırdı.

AX1234hSI0104hSPFFFAhZF0Kod içindeki dizgi (CS:0104h)'H'0104'i'010500h0106↑ SI

SI = 0104h: dizginin ilk baytı.

AX0E48hSI0105hSPFFFAhZF0Kod içindeki dizgi (CS:0104h)'H'0104'i'010500h0106↑ SI

AL = 'H' ≠ 0 (ZF = 0): SI ilerler, H yazılır.

AX0E69hSI0106hSPFFFAhZF0Kod içindeki dizgi (CS:0104h)'H'0104'i'010500h0106↑ SI

AL = 'i' ≠ 0: SI = 0106h, i yazılır.

AX0E00hSI0106hSPFFFAhZF1Kod içindeki dizgi (CS:0104h)'H'0104'i'010500h0106↑ SI

AL = 0 → ZF = 1, JZ bitti'ye atlar. Sondaki 0 dizginin bittiğini gösterir.

AX1234hSI0000hSPFFFEhZF1Kod içindeki dizgi (CS:0104h)'H'0104'i'010500h0106

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
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.

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?

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 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.

Son

Bölüm 5: 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.