Standart C Programlama Dili


C.7.1. Birleştirici İle Bağlayıcının Kullanılması

Uyarı
Kitabın bu kısmı eski bilgiler içermektedir. Ancak, okuyucunun yararına olabileceği düşünülerek aynen korunmuştur.

Bir C programında, fonksiyon isimleri dışsal simgelermiş gibi işlem görürler ve bağlayıcı tarafından kullanılmaları için, amaç program dosyasına kaydedilirler. Fakat bir farkla: C derleyicisi her fonksiyon isminin önüne bir altçizgi ekler. Örneğin:

xyz ()
{
  
}

fonksiyon tanımında, fonksiyon ismi amaç programda _xyz şeklinde kaydedilir. (Eski) Standarda göre, dışsal tanıtıcı sözcüklerde, anlamlı karakter sayısı en az 8’dir. Ayrıca, küçük büyük harf ayırımı yapılmayabilir.

Bir C fonksiyonu başka bir C fonksiyonunu çağırdığında, çağrıdaki argümanlar ve dönüş adresi, yığıt adı verilen bir veri yapısı içinde çağrılan fonksiyona geçirilir ve çağrılan fonksiyon değişiklikleri bu yığıt içinde yapar. Bundan dolayı, çağıran ile çağrılan fonksiyonun bu yığıtı nasıl değiştirdiğini anlamak çok önemlidir.

Yığıt, belleğin büyük adreslerinden küçük adreslerine doğru büyür. C derleyicisi, çağrıdaki argümanları, argüman listesindeki sıralarına göre, fakat sağdan başlayarak yığıta yerleştirir. Böylece, yığıta en son itilen ve bundan dolayı en düşük adreste bulunan argüman en soldaki, yani argüman listesindeki ilk argümandır. Çağıran yordam tarafından yığıta en son itilen şey ise dönüş adresidir. Çağrılan yordam Taban Yazmaç BP’nin içeriğini saklayarak, yerel verileri için yer ayırarak ve, SI ile DI gibi, içerikleri değişebilecek olan yazmaçların içeriklerini saklayarak yığıtta değişiklikler yapar. Aşağıdaki çizelge yığıtın içeriğini göstermektedir.

n’inci argüman (büyük adres)
çağıran fonksiyon n-1’inci argüman
tarafından değiştirilen
yığıt bölümü birinci argüman
dönüş adresi
çağrılmış fonksiyon saklanmış BP ← BP
tarafından değiştirilen yerel veriler
yığıt bölümü saklanmış yazmaçlar ← SP (küçük adres)

Her argüman için kullanılan bayt sayısı argümanın tipi ve, değerle veya referansla çağrı gibi, argümanı geçirmek için kullanılan yönteme bağlıdır. Referansla çağrı durumunda, bir adres geçirildiğine göre, bu sayı adresin yakın/uzak niteliğine de bağlıdır. Aynı durum dönüş adresi için de söz konusudur. Her biri için kullanılan bayt sayısı şöyledir:

YöntemTipBayt
değerleshort, int2
değerlelong4
değerlefloat4
değerledouble8
referanslayakın2
referanslauzak4
dönüş adresiyakın2
dönüş adresiuzak4

Program minik, küçük veya kısa bellek modelinde derlenmişse dönüş adresi yakın, aksi takdirde uzaktır. Uzak adresler kesim:uzaklık şeklinde olurlar.

C’de dizi dışındaki tüm veri yapılarının değerle, dizilerin ise referansla geçirildiğini anımsayın. Eğer bir dizinin değerle geçirilmesi isteniyorsa, o zaman değerle geçirilen bir yapının tek üyesi olarak tanımlanmalıdır.

Çağrılan yordam, işini bitirdikten sonra, hesapladığı değeri şu şekilde döndürür:

Döndürülen değerYazmaç
1 baytAL
2 baytAX
4 baytyüksek baytlar DX’te, düşük baytlar AX’te
> 4 baytdeğerin adresi DX:AX’te

Aşağıdaki örnekte, birleştirici dilde yazılmış xyz adındaki fonksiyonu çağıran bir C main fonksiyonu gösterilmektedir:

extern int xyz (int, int);
main ()
{
  
  xyz(3,5);
  
}
.MODEL SMALL
.CODE
       PUBLIC _xyz
_xyz   PROC
       push   bp        ; Taban gösterge yazmacını sakla
       mov    bp,sp     ; Yığıtta  boyunda yeni
       sub    sp,     ;   bir taban bölge aç
       push   si        ; SI ve DI yazmaçlarını sakla
       push   di        ;
       pushf            ; Bayrak yazmacını sakla
       mov    ax,[bp+4] ; İlk argümanı AX'e taşı
       mov    cx,[bp+6] ; İkinci argümanı CX'e taşı
                      ; xyz'nin hesaplaması
                      ;   gereken şeyi hesapla
       mov    ax,     ; Dönüş değerini koy
       popf             ; Bayrak yazmacını geri al
       pop    di        ; DI ve SI yazmaçlarını geri al
       pop    si
       mov    sp,bp     ; Yığıtı temizle
       pop    bp        ; Eski BP'yi geri al
       ret              ; Çağırana dön
_xyz   ENDP
       END

Programları ayrı ayrı amaç dosyaları içine derleyin ve birleştirin; daha sonra bu iki dosyayı tek bir yürütülebilir dosya şeklinde bağlayın.