Bölüm 7: Prosedürler

Bölüm 7: Prosedürler · Çalışma Soruları
PROC / ENDPCALL ve RETDönüş adresiCALL makine koduİç içe çağrılarParametrelerYazmaç korumaSık yapılan hatalar
Sercan KÜLCÜ

Çoktan Seçmeli · Tanımlama

Soru 1: Direktif mi, Komut mu?

Aşağıdakilerden hangisi assembler direktifi değildir, işlemcinin yürüttüğü bir komuttur?

C: CALL (yakın çağrıda E8) ve RET (C3) makine koduna çevrilen komutlardır. PROC/ENDP prosedürün başını, sonunu ve türünü (NEAR/FAR) assembler'a bildirir; END kaynağın bittiğini söyler. Direktifler bellekte yer kaplamaz.

Kod Okuma · Tanımlama

Soru 2: Prosedüre Düşmek

Programcı ana programın sonuna RET yazmayı unutmuş. Program bittiğinde AX kaçtır? ikiyle prosedürü kaç kez çalışır?

ORG 100h
MOV AX, 2
CALL ikiyle
ikiyle PROC
ADD AX, AX
RET
ikiyle ENDP
Cevabı göster

AX = 0008h; prosedür iki kez çalışır.

  • CALL ikiyle: dönüş adresi 0106h itilir; AX = 2 + 2 = 4; RET 0106h'ye döner.
  • 0106h, prosedürün kendi ilk komutudur: işlemci ENDP'yi "görmez", akış prosedüre düşer. AX = 8.
  • Bu RET yığından DOS'un koyduğu 0000h'yi alır ve program sonlanır.

Düzeltme: CALL'dan sonra RET; prosedürler ana programın RET'inden sonra yazılır.

Çoktan Seçmeli · CALL ve RET

Soru 3: RET Ne Yapar?

Yakın (near) bir prosedürün sonundaki RET komutu ne yapar?

A: RET yığının üstündeki sözcüğü dönüş adresi olarak IP'ye alır ve SP'yi 2 artırır (POP IP gibi). B, CALL'ın ilk yarısını anlatır. CS ile IP'yi birlikte alan uzak dönüş RETF'tir (D). Dönüş adresi yazmaçta değil, yığında saklanır (C).

Çıktı Sorusu · CALL ve RET

Soru 4: CALL, RET ve Dönüş Adresi

CALL KARE çalışınca yığına ne yazılır, SP ve IP ne olur? Program bittiğinde AX ve DX nedir? (Yorumlar komut adresleridir.)

ORG 100h
MOV AX, 3        ; 0100h
CALL KARE        ; 0103h
ADD AX, 1        ; 0106h
RET              ; 0109h
KARE PROC
MUL AX           ; 010Ah
RET              ; 010Ch
KARE ENDP
Cevabı göster

CALL, sonraki komutun adresini iter: SP = FFFCh, [FFFCh] = 0106h; IP ← 010Ah (KARE).

MUL AX: DX:AX ← 3 × 3 = 9 → AX = 0009h, DX = 0000h (16 bitlik MUL DX'i de yazar).

KARE'deki RET 0106h'yi IP'ye alır, SP = FFFEh. ADD AX, 1 → AX = 000Ah, DX = 0000h; son RET programı bitirir.

Hesap Sorusu · CALL ve RET

Soru 5: CALL'ın Makine Kodu

Yakın CALL 3 bayttır: E8 + 16 bitlik uzaklık. (a) 0100h'deki CALL m1, m1 0107h'de. (b) 0120h'deki CALL p, p 0100h'de. Makine kodları nedir, yığına hangi adres itilir?

Cevabı göster

Uzaklık = hedef − (CALL adresi + 3).

(a) 0107h − 0103h = 0004h → E8 04 00; yığına 0103h itilir.

(b) 0100h − 0123h = −23h = FFDDh → E8 DD FF; yığına 0123h itilir.

16 bitlik değer little-endian saklanır: önce düşük bayt. Hedef mutlak adres olarak değil uzaklık olarak saklandığından kod bellekte taşınsa da çalışır.

Çoktan Seçmeli · CALL ve RET

Soru 6: Üç CALL, Hiç RET

SP = FFFEh iken arka arkaya üç yakın CALL yürütülüyor (iç içe çağrılar, henüz hiç RET yok). SP kaç olur?

D: Her yakın CALL yığına 2 baytlık dönüş adresi iter: FFFEh − 3 × 2 = FFF8h. Yığın aşağı doğru büyür, SP azalır (C yanlış). FFF4h 4 baytlık uzak çağrılara, FFFBh 1 baytlık itmeye karşılık gelirdi; 8086 yığına hep sözcük yazar.

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

Soru 7: İç İçe Çağrılar

main, A'yı; A da B'yi çağırıyor. Yığında en çok kaç dönüş adresi birikir? RET'ler hangi sırayla döner? Sonunda AX nedir?

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

AX = 1. SP = FFFEh; yığında DOS'un 0000h'si var.

AX0001hSPFFFChYığınFFFA····FFFC0106h← SPFFFE0000h

CALL A: dönüş adresi 0106h itilir (SP = FFFCh), IP = 0107h.

AX0003hSPFFFChYığınFFFA····FFFC0106h← SPFFFE0000h

A içinde AX = 3.

AX0003hSPFFFAhYığınFFFA010Dh← SPFFFC0106hFFFE0000h

A içinden CALL B: 010Dh itilir, SP = FFFAh. Yığında iki dönüş adresi var.

AX0006hSPFFFAhYığınFFFA010Dh← SPFFFC0106hFFFE0000h

B: AX = AX + AX = 6.

AX0006hSPFFFChYığınFFFA····FFFC0106h← SPFFFE0000h

B'nin RET'i en üstteki 010Dh'yi alır: A'ya döner (LIFO). SP = FFFCh.

AX000AhSPFFFChYığınFFFA····FFFC0106h← SPFFFE0000h

A devam eder: AX = 10 = 000Ah.

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

A'nın RET'i 0106h'yi alır: main'e döner, SP = FFFEh. Son çağrılan ilk döndü. main'in RET'i programı bitirir: AX = 000Ah.

ORG 100h
MOV AX, 1
CALL A
RET
A PROC
ADD AX, 2
CALL B
ADD AX, 4
RET
A ENDP
B PROC
ADD AX, AX
RET
B ENDP

Çıktı Sorusu · Parametreler

Soru 8: Yazmaçlarla Parametre

m2 prosedürü parametrelerini AL ve BL'de alır, sonucu AX'te verir. Program bittiğinde AX nedir? İkinci çağrı neden farklı sonuç verir?

ORG 100h
MOV AL, 5
MOV BL, 3
CALL m2
CALL m2
RET
m2 PROC      ; Girdi: AL, BL
MUL BL       ; Çıktı: AX = AL * BL
RET
m2 ENDP
Cevabı göster

1. çağrı: AX = 5 × 3 = 15 = 000Fh. AL artık 0Fh.

2. çağrı: AX = 0Fh × 3 = 45 = 002Dh.

MUL BL sonucu AX'e yazar ve AL'yi değiştirir; ikinci çağrının birinci parametresi, ilk çağrının sonucu olur. Prosedürün girdi, çıktı ve bozduğu yazmaçlar (burada AX, CF, OF) başına açıklama olarak yazılmalıdır.

Çoktan Seçmeli · Parametreler

Soru 9: Parametre Yolları

Parametre geçirme yolları için hangisi doğrudur?

B: Adres (işaretçi) ile geçirmede yalnızca dizinin başlangıç adresi verilir; veri kopyalanmaz (print_me örneğinde SI). Yazmaçlar en hızlı yoldur (A). Bellek değişkenleri kalıcıdır (C). 8086'da SP taban yazmacı olamaz; yığındaki parametreler BP ile ([BP+4]) okunur (D).

Hata Bulma · Parametreler

Soru 10: Döngü Neden Bitmiyor?

Program 3 kez "**" yazmak için yazıldı ama hiç bitmiyor. Neden? İki düzeltme önerin.

ORG 100h
MOV CX, 3
tekrar:
CALL yaz
LOOP tekrar
RET
yaz PROC
MOV CX, 2
ic:
MOV AL, '*'
MOV AH, 0Eh
INT 10h
LOOP ic
RET
yaz ENDP
Cevabı göster

yaz, ana döngünün sayacı CX'i kendi döngüsü için kullanıyor. Prosedür dönerken CX = 0'dır. Ana döngüdeki LOOP CX'i FFFFh yapar ve geri atlar; her çağrı CX'i yine 0 yaptığı için bu sonsuza dek sürer: ekrana durmadan * yazılır.

  • Prosedürde koruma: girişte PUSH CX, RET'ten önce POP CX. Böylece çıktı 6 yıldız olur.
  • Ya da çağıran taraf korur: PUSH CX / CALL yaz / POP CX.

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

Soru 11: Harf Dönüştüren Prosedür

buyuk prosedürü AL'deki küçük harfi büyüğe çevirir, diğer karakterleri değiştirmez. Döngü bittiğinde metin ne olur?

AL00hSI011DhCX0003hmetin (bellek)'a'011D'1'011E'b'011F↑ SI

SI = metin'in adresi (011Dh), CX = 3 karakter.

AL41hSI011DhCX0003hmetin (bellek)'A'011D'1'011E'b'011F↑ SI

Tur 1: AL = 'a' (61h). 'a' ≤ AL ≤ 'z' → SUB AL, 20h: 'A' (41h). RET'ten sonra belleğe yazıldı.

AL31hSI011EhCX0002hmetin (bellek)'A'011D'1'011E'b'011F↑ SI

Tur 2: AL = '1' (31h) < 'a' → CF = 1, JB son: değişmeden döner, bellekte '1' kalır. JB işaretsiz karşılaştırmadır.

AL42hSI011FhCX0001hmetin (bellek)'A'011D'1'011E'B'011F↑ SI

Tur 3: 'b' → 'B'.

AL42hSI0120hCX0000hmetin (bellek)'A'011D'1'011E'B'011F

LOOP: CX = 0, döngü biter. metin = 'A1B'. buyuk CX'e dokunmadığı için LOOP sayacı güvende; girdi ve çıktı AL'dedir.

ORG 100h
LEA SI, metin
MOV CX, 3
dongu:
MOV AL, [SI]
CALL buyuk
MOV [SI], AL
INC SI
LOOP dongu
RET
buyuk PROC
CMP AL, 'a'
JB son
CMP AL, 'z'
JA son
SUB AL, 20h
son:
RET
buyuk ENDP
metin DB 'a1b'

Çoktan Seçmeli · Sık Yapılan Hatalar

Soru 12: CALL Yerine JMP

Programcı CALL ekle yerine yanlışlıkla JMP ekle yazmış. .COM programında ekle'nin sonundaki RET ne yapar?

ORG 100h
MOV AX, 1
JMP ekle
MOV BX, 9   ; çalışır mı?
RET
ekle PROC
ADD AX, 5
RET
ekle ENDP

A: JMP dönüş adresi itmez. RET yığının üstünde ne varsa onu IP'ye alır; ana program bir şey itmediyse bu DOS'un 0000h'sidir: PSP'deki INT 20h programı sessizce bitirir ve JMP'ten sonraki satırlar hiç çalışmaz. Yığında başka bir değer olsaydı rastgele bir adrese dönülürdü.

Çoktan Seçmeli · Sık Yapılan Hatalar

Soru 13: Sonucu Korumak

Bir prosedür sonucunu AX'te döndürüyor; girişte PUSH AX, RET'ten önce POP AX yapıyor. Ne olur?

C: POP AX, girişteki değeri geri yükleyerek hesaplanan sonucu siler. PUSH/POP sayısı eşit olduğu için yığın dengelidir ve RET doğru döner (A). Kural: prosedür kullandığı yazmaçları korur, ama sonuç döndüren yazmacı korumaz.

Kod Yazma · Örnek Programlar

Soru 14: Büyük Olanı Döndür

AX ve BX'teki işaretsiz sayılardan büyüğünü AX'te döndüren buyugu prosedürünü yazın. Prosedür başka yazmacı bozmasın. Çağırma örneği de verin.

Cevabı göster
; Girdi: AX, BX (işaretsiz)
; Çıktı: AX = büyük olan
buyugu PROC
    CMP AX, BX
    JAE tamam
    MOV AX, BX
tamam:
    RET
buyugu ENDP
MOV AX, 5
MOV BX, 9
CALL buyugu     ; AX = 9

İşaretsiz karşılaştırma için JAE (CF = 0). Yalnızca AX değişir; başka yazmaç kullanılmadığı için PUSH/POP gerekmez. Denendi: (5, 9) → 9, (9, 5) → 9, (7, 7) → 7, (FFFFh, 1) → FFFFh; CX ve BX korunur. İşaretli sayılar için JGE kullanılırdı.

Adım Adım Çalıştırma · Sık Yapılan Hatalar

Soru 15: Kendini Çağıran Prosedür

fakt kendini çağırarak AX = CX! hesaplıyor (CX = 3). Yığın en çok ne kadar derinleşir? Durma koşulu olmasaydı ne olurdu?

AX0001hCX0003hSPFFFChYığınFFF8····FFFA····FFFC0109h← SPFFFE0000h

CALL fakt: 0109h itildi, SP = FFFCh. CX = 3.

AX0003hCX0002hSPFFFAhYığınFFF8····FFFA0115h← SPFFFC0109hFFFE0000h

CX = 3 > 1: AX = 1 × 3 = 3, CX = 2; kendini çağırır: 0115h itildi, SP = FFFAh.

AX0006hCX0001hSPFFF8hYığınFFF80115h← SPFFFA0115hFFFC0109hFFFE0000h

AX = 3 × 2 = 6, CX = 1; yine CALL: üçüncü dönüş adresi, SP = FFF8h.

AX0006hCX0001hSPFFFAhYığınFFF8····FFFA0115h← SPFFFC0109hFFFE0000h

CMP CX, 1 → CX ≤ 1, JBE bitti: durma koşulu. İlk RET 0115h'ye döner (SP = FFFAh).

AX0006hCX0001hSPFFFChYığınFFF8····FFFA····FFFC0109h← SPFFFE0000h

İkinci RET de 0115h'ye döner (SP = FFFCh): her RET bir dönüş adresi tüketir, 0115h'deki RET art arda çalışır.

AX0006hCX0001hSPFFFEhYığınFFF8····FFFA····FFFC····FFFE0000h← SP

Üçüncü RET 0109h'ye döndü, SP = FFFEh. Ana program: AX = 6. Durma koşulu (CMP/JBE) olmasaydı her çağrı 2 bayt yer, yığın kodun üzerine kadar büyürdü (yığın taşması).

ORG 100h
MOV CX, 3
MOV AX, 1
CALL fakt
RET
fakt PROC
CMP CX, 1
JBE bitti
MUL CX
DEC CX
CALL fakt
bitti:
RET
fakt ENDP

Çoktan Seçmeli · Sık Yapılan Hatalar

Soru 16: Ad Uyuşmazlığı

Hangisi assembler'ın derleme sırasında yakalayabileceği bir prosedür hatasıdır?

D: PROC ve ENDP'deki adlar aynı olmalıdır; uyuşmazlık bir sözdizimi hatasıdır. Diğerleri geçerli koddur ve yalnızca çalışma sırasında ortaya çıkar: RET yoksa akış prosedürden sonraki koda düşer, PUSH/POP dengesizliğinde RET yanlış adrese döner, bozulan CX döngüyü şaşırtır.

Son

Bölüm 7: Prosedürler: Çalışma Soruları
Konu anlatımı: prosedürler sunumu · Terim sözlüğü
1 / 1 Sercan KÜLCÜ, Tüm hakları saklıdır.