Bölüm 8: Makrolar

Bölüm 8: Makrolar · Çalışma Soruları
Tanım ve genişletmeParametre tuzaklarıMakro ve prosedürBoyut hesabıLOCALPUTCPOWERemu8086.inc
Sercan KÜLCÜ

Çoktan Seçmeli · Makro Kavramı

Soru 1: Makronun Tanımı

Makrolar için aşağıdakilerden hangisi doğrudur?

B: Derleyici bir makro çağrısını açabilmek için tanımı önceden görmüş olmalıdır. Makro derleme zamanında metin olarak genişletilir, CALL kullanılmaz; hiç kullanılmayan makro koda tek bayt eklemez; her kullanım ayrı bir kopya üretir. Tek kopya, prosedürün özelliğidir.

Çıktı Sorusu · Makro Kavramı

Soru 2: Makro Genişletme

Program bittiğinde AX ne olur? Assembler bu kaynaktan kaç makine komutu üretir?

TOPLA MACRO a, b
    MOV AX, a
    ADD AX, b
ENDM

ORG 100h
TOPLA 5, 7
TOPLA AX, 3
RET
Cevabı göster

AX = 000Fh (önce 000Ch); 5 komut.

MOV AX, 5    ; TOPLA 5, 7
ADD AX, 7    ; AX = 000Ch
MOV AX, AX   ; TOPLA AX, 3
ADD AX, 3    ; AX = 000Fh
RET

Her çağrının yerine gövde kopyalanır ve parametreler metin olarak yerleştirilir. İkinci çağrıda a = AX olduğundan MOV AX, AX üretilir: zararsız ama gereksiz. Makroda CALL/RET olmadığı için yığın kullanılmaz.

Çıktı Sorusu · Makro Kavramı

Soru 3: Genişletilmiş Kod Geçerli mi?

İlk çağrıdan sonra AX ve BX ne olur? İkinci çağrı derlenir mi?

TAKAS MACRO a, b
    PUSH a
    PUSH b
    POP  a
    POP  b
ENDM

ORG 100h
MOV AX, 1111h
MOV BX, 2222h
TAKAS AX, BX
TAKAS AX, 5
RET
Cevabı göster

İlk çağrı PUSH AX / PUSH BX / POP AX / POP BX olur: son giren ilk çıktığı için AX = 2222h, BX = 1111h (takas).

İkinci çağrı PUSH AX / PUSH 5 / POP AX / POP 5 olur ve derlenmez: anlık değer itme (PUSH 5) 80186 ile gelmiştir, 8086'da yoktur; POP 5 ise hiçbir işlemcide anlamlı değildir (sabite yazılamaz).

Makro tanımı hatasızdır; derleyici yalnızca metni değiştirir, hata genişletilmiş satırlarda ortaya çıkar.

Adım Adım Çalıştırma · Makro Kavramı

Soru 4: Parametre Tuzağı

TOPLA2 MACRO a, b · MOV AX, a · ADD AX, b · MOV BX, AX · ENDM makrosu AX = 3, CX = 4 iken TOPLA2 CX, AX ile çağrılıyor. Genişletilmiş kod çalışınca BX ne olur?

AX0003hBX0000hCX0000h

AX = 3.

AX0003hBX0000hCX0004h

CX = 4. Programcı TOPLA2 CX, AX ile BX = 4 + 3 = 7 bekliyor.

AX0004hBX0000hCX0004h

Makronun 1. satırı MOV AX, a → MOV AX, CX: AX = 0004h. Eski AX (3) kayboldu.

AX0008hBX0000hCX0004h

2. satır ADD AX, b → ADD AX, AX: b parametresi "AX" metnidir ve AX artık 4'tür → AX = 0008h.

AX0008hBX0008hCX0004h

BX = 0008h, beklenen 7 değil. Parametre bir değer değil metindir; değeri kullanıldığı satırda okunur. Makronun değiştirdiği yazmaç (AX) parametre olarak verilmemelidir.

ORG 100h
MOV AX, 3
MOV CX, 4
MOV AX, CX     ; TOPLA2 CX, AX
ADD AX, AX
MOV BX, AX
RET

Çoktan Seçmeli · Makro ve Prosedür

Soru 5: Makro mu, Prosedür mü?

Makrolar ve prosedürler için aşağıdakilerden hangisi doğrudur?

C: Makro derleme anında metin olarak açılır: kod büyür ama CALL/RET ve yığın erişimi olmadığı için daha hızlıdır. Prosedür bellekte tek kopyadır; her çağrı CALL ile ona gider, RET ile döner. Etiketli bir makro iki kez kullanılırsa etiket iki kez tanımlanır; bunu LOCAL direktifi önler.

Çoktan Seçmeli · Makro ve Prosedür

Soru 6: 25 Kullanımda Boyut

PUTC makrosunun her kopyası 8 bayttır. Aynı iş, gövdesi 8 bayt + RET (1 bayt) olan bir prosedür ve her kullanımda 3 baytlık yakın CALL ile de yapılabilir. 25 kullanımda kod boyutları nedir?

A: Makro: 25 × 8 = 200 bayt. Prosedür: gövde bir kez (8 + 1 = 9 bayt) ve 25 × 3 = 75 bayt CALL → 84 bayt. 75 bayt yalnızca CALL'ları sayar, gövdeyi unutur; 225 bayt makro kopyasını 9 bayt sayar (makroda RET yoktur); 209 bayt gövdeyi her çağrıda yeniden sayar.

Hesap Sorusu · Makro ve Prosedür

Soru 7: Başa Baş Noktası

Gövdesi n bayt olan bir iş k yerde kullanılıyor. Makro k · n bayt, prosedür (n + 1) + 3k bayt tutar.

  1. n = 8 için kaç kullanımdan itibaren prosedür daha küçüktür?
  2. n = 3 için durum nedir?
  3. Her CALL + RET çifti yaklaşık 27 saat turu ise 4,77 MHz'lik 8086'da 10 000 çağrı kaç ms ek süre getirir?
Cevabı göster
  1. 8k > 9 + 3k → 5k > 9 → k ≥ 2. k = 1: 8 ve 12 bayt (makro küçük); k = 2: 16 ve 15 bayt (prosedür küçük).
  2. 3k ile 4 + 3k: makro her zaman daha küçüktür. Gövde bir CALL kadar kısaysa prosedür yalnızca RET ve çağrı maliyeti ekler.
  3. 10 000 × 27 = 270 000 tur; 270 000 ÷ 4 770 000 Hz ≈ 56,6 ms. Makroda bu süre yoktur.

Boyut kullanım sayısıyla, hız farkı çağrı sayısıyla büyür: sık çalışan kısa kod makroya, uzun ve çok yerde kullanılan kod prosedüre uygundur.

Çoktan Seçmeli · Makro ve Prosedür

Soru 8: Hangisi Makro Olmalı?

Aşağıdaki durumların hangisinde makro seçmek en uygundur?

D: İki komutluk işte CALL + RET maliyeti işin kendisinden büyüktür; makro hem hızlı hem de kısa kalır. 300 baytlık sıralama makroyla 900 bayt, prosedürle yaklaşık 309 bayt tutar; boyut kritikse 200 kopya (1600 bayt) yerine prosedür (609 bayt) seçilir. Kendini çağıran bir makronun genişletmesi koşullu derleme olmadan hiç bitmez.

Çoktan Seçmeli · Etiketler ve LOCAL

Soru 9: Aynı Etiket İki Kez

Aşağıdaki program derlenirken ne olur?

BEKLE MACRO
ilk: DEC CX
     JNZ ilk
ENDM

MOV CX, 5
BEKLE
MOV CX, 9
BEKLE

B: Genişletmeden sonra kodda iki ilk: satırı vardır; derleyici hangisine atlanacağını bilemez ve hata verir. Çözüm makronun ilk satırına LOCAL ilk yazmaktır: her genişletmede etiket benzersiz bir adla (MASM'da ??0000, ??0001 …) değiştirilir.

Adım Adım Çalıştırma · Etiketler ve LOCAL

Soru 10: LOCAL ile İki Kopya

MAKS MACRO a, b · LOCAL bitti · MOV AX, a · CMP AX, b · JGE bitti · MOV AX, b · bitti: · ENDM makrosu iki kez kullanıldı. AX ve DX ne olur? JGE yerine JAE yazılsaydı ilk çağrı ne verirdi?

AX0000hBXFFFEhDX0000hSF0OF0CF0

BX = −2 = FFFEh (ikiye tümleyen).

AXFFFEhBXFFFEhDX0000hSF0OF0CF0

Birinci genişletme: AX ← BX = FFFEh.

AXFFFEhBXFFFEhDX0000hSF1OF0CF0

CMP AX, 1: −2 − 1 = −3 → SF = 1, OF = 0. İşaretsiz yorumda FFFEh > 1 olduğundan ödünç yok: CF = 0.

AXFFFEhBXFFFEhDX0000hSF1OF0CF0

JGE (SF = OF ister): SF ≠ OF → −2 ≥ 1 değil, atlamaz.

AX0001hBXFFFEhDX0000hSF1OF0CF0

AX ← 1: büyük olan b. LOCAL sayesinde etiket bu kopyada ??0000 oldu.

AX0001hBXFFFEhDX0001hSF1OF0CF0

DX = 0001h: ilk sonucun kopyası.

AX0001hBXFFFEhDX0001hSF1OF0CF0

İkinci genişletme MAKS AX, -5: MOV AX, AX etkisiz.

AX0001hBXFFFEhDX0001hSF0OF0CF1

CMP AX, −5: 1 − (−5) = 6 → SF = 0, OF = 0 (işaretsiz yorumda 1 < FFFBh olduğundan CF = 1).

AX0001hBXFFFEhDX0001hSF0OF0CF1

JGE: SF = OF → 1 ≥ −5, ??0001'e atlar. Bu kopyanın etiketi farklı olduğu için çakışma yok. Sonuç AX = DX = 0001h.

AXFFFEhBXFFFEhDX0000hSF1OF0CF0

JAE ile: JAE işaretsiz karşılaştırır, CF = 0 olduğundan ilk çağrı atlar ve AX = FFFEh (65 534) kalırdı. İşaretli büyüklük için JGE/JG kullanılır.

ORG 100h
MOV BX, -2
MOV AX, BX     ; MAKS BX, 1
CMP AX, 1
JGE ??0000
MOV AX, 1
??0000:
MOV DX, AX
MOV AX, AX     ; MAKS AX, -5
CMP AX, -5
JGE ??0001
MOV AX, -5
??0001:
RET

Çıktı Sorusu · PUTC Makrosu

Soru 11: Görünmez Yan Etki

Ekranda ne görünür? Makroya hangi iki satır eklenirse ekranda -5 görünür?

PUTC2 MACRO c        ; PUSH/POP yok
    MOV AL, c
    MOV AH, 0Eh
    INT 10h
ENDM

ORG 100h
MOV AL, '5'
PUTC2 '-'
MOV AH, 0Eh
INT 10h          ; '5' yazılsın
RET
Cevabı göster

Ekran: --

Makro AL'ye '-' yazdığı için çağıranın AL'deki '5' değeri kaybolur; sonraki INT 10h yine '-' yazar.

Gövdenin başına PUSH AX, sonuna POP AX eklenir (PUTC makrosundaki gibi). AX korunur ve ekranda -5 görünür.

Çoktan Seçmeli · PUTC Makrosu

Soru 12: RET Unutulursa

ORG 100h · PUTC 'A' · PUTC 'B' · RET programından son satırdaki RET silinirse ne olur?

C: İşlemci kod ile veriyi ayırt etmez: son komuttan sonra bellekte ne varsa onu çözüp yürütür ve sistem kilitlenebilir. Makro genişletme yalnızca gövdeyi kopyalar; POP AX yalnızca AX'i geri yükler; INT 10h, IRET ile programa döner.

Adım Adım Çalıştırma · POWER Makrosu

Soru 13: POWER 3, 4

base = 3, exponent = 4 için POWER makrosunun açılımı çalışıyor. Her adımda AX, CX, DX ne olur? result kaç olur?

AX0001hBX0000hCX0000hDX0000h

Geçici sonuç AX = 1.

AX0001hBX0000hCX0004hDX0000h

CX ← exponent = 4 (döngü sayısı).

AX0001hBX0003hCX0004hDX0000h

BX ← base = 3.

AX0003hBX0003hCX0004hDX0000h

1. tur: DX:AX = 1 × 3 = 0003h. Üst yarı DX = 0 → CF = OF = 0.

AX0003hBX0003hCX0003hDX0000h

LOOP: CX = 3 ≠ 0 → powerloop.

AX0009hBX0003hCX0003hDX0000h

2. tur: AX = 3 × 3 = 0009h.

AX0009hBX0003hCX0002hDX0000h

CX = 2.

AX001BhBX0003hCX0002hDX0000h

3. tur: AX = 9 × 3 = 001Bh (27).

AX001BhBX0003hCX0001hDX0000h

CX = 1.

AX0051hBX0003hCX0001hDX0000h

4. tur: AX = 27 × 3 = 0051h (81).

AX0051hBX0003hCX0000hDX0000h

CX = 0 → döngüden çıkılır.

AX0051hBX0003hCX0000hDX0000h

result (0117h) ← 0051h = 34 = 81. MUL her turda DX'i de yazdı; makro AX, BX, CX ve DX'i değiştirir.

ORG 100h
mov ax, 1        ; POWER base, exponent, result
mov cx, exponent
mov bx, base
powerloop:
mul bx           ; DX:AX = AX * BX
loop powerloop
mov result, ax
ret
base     dw 3
exponent dw 4
result   dw ?

Çıktı Sorusu · POWER Makrosu

Soru 14: Üs Sıfır Olunca

POWER makrosunun (JCXZ denetimi olmayan) ilk sürümü exponent = 0 ile çağrılıyor.

  1. MUL kaç kez çalışır?
  2. base = 2 ise result ne olur?
  3. base = 1 ise result ne olur? Bu sonuç makronun doğru olduğunu gösterir mi?
Cevabı göster
  1. LOOP önce CX'i azaltır: 0 → FFFFh ≠ 0. Döngü 65 536 kez döner.
  2. 216'dan sonra AX'in alt 16 biti sıfırdır ve öyle kalır: result = 0000h (beklenen 20 = 1).
  3. result = 0001h: 1 kaç kez çarpılsa 1'dir. Sonuç tesadüfen doğrudur; hata yine vardır (65 536 gereksiz MUL).

Düzeltme: MOV CX, e ardından JCXZ p_end; e = 0 ise AX = 1 doğrudan yazılır.

Çoktan Seçmeli · POWER Makrosu

Soru 15: İç İçe Genişletme

PUTC makrosunu iki kez çağıran PRINT2 MACRO c1, c2 makrosunun PRINT2 'O', 'K' çağrısı kaç makine komutu ve kaç bayt üretir?

A: Önce PRINT2 açılır: iki PUTC satırı. Her PUTC de 5 komuta (PUSH AX, MOV AL, MOV AH, INT 10h, POP AX) ve 1 + 2 + 2 + 2 + 1 = 8 bayta açılır. 2 komut/6 bayt iki CALL'a, 5 komut/8 bayt tek bir PUTC'ye karşılık gelirdi.

Çoktan Seçmeli · POWER Makrosu

Soru 16: Kütüphane ve Kod Boyutu

include 'emu8086.inc' ile onlarca makro içeren kütüphane eklendi; program yalnızca GOTOXY ve PUTC kullanıyor. Hangisi doğrudur?

D: Kullanılmayan makro kod üretmez; büyük bir kütüphaneyi eklemek çalıştırılabilir dosyayı büyütmez. INCLUDE derleme anında dosyanın metnini kaynağa ekler; .COM programlarında da kullanılır. Kütüphanedeki prosedürler ise DEFINE_… makrolarıyla ayrıca tanımlanır.

Kod Yazma · POWER Makrosu

Soru 17: Kaydırmalı Çarpma Makrosu

Bir yazmacı ya da sözcük değişkenini 2n ile çarpan CARP2N deg, n makrosunu MUL kullanmadan yazın. CX dışında yazmaç kullanmasın ve CX'in değeri korunsun. sayi dw 5 için CARP2N sayi, 3 ne verir? CARP2N CX, 2 çağrısında ne olur?

Cevabı göster
CARP2N MACRO deg, n
    PUSH CX
    MOV  CL, n     ; 8086: sayı CL'de
    SHL  deg, CL
    POP  CX
ENDM

Etiket olmadığı için LOCAL gerekmez. 8086'da 1'den büyük kaydırma sayısı yalnızca CL ile verilir; SHL deg, n 80186 komutudur.

CARP2N sayi, 3: 5 × 8 = 40 (0028h).

CARP2N CX, 2: CX = 7 ise MOV CL, 2 CX'i 0002h yapar, SHL sonucu 0008h olur, POP CX ise eski 7'yi geri yükler: CX değişmez. Makronun koruduğu yazmaç parametre olarak verilmemelidir.

Son

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