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öntem | Tip | Bayt |
---|---|---|
değerle | short , int | 2 |
değerle | long | 4 |
değerle | float | 4 |
değerle | double | 8 |
referansla | yakın | 2 |
referansla | uzak | 4 |
dönüş adresi | yakın | 2 |
dönüş adresi | uzak | 4 |
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ğer | Yazmaç |
---|---|
1 bayt | AL |
2 bayt | AX |
4 bayt | yüksek baytlar DX’te, düşük baytlar AX’te |
> 4 bayt | değ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.