32 Bit Intel Ailesinde çağırma biçimi (calling convention) kavramı

06:53 ,
Fonksiyonların çağrılması ve geri dönüş değerlerinin alınması konusundaki belirlemelere çağırma biçimi (calling convention) denilmektedir. Derleyicilerin bir fonksiyonu derlerken stack'e parametreleri hangi sirayla push edeceginin veya parametrelerin kullanılacak register'a hangi sıraya göre atılacağı gibi kuralların belirlendiği modeldir. Dolayisiyla farkli diller arasinda veya farklı ortamlar arasinda kullanilacak olan fonksiyonlarin bildiriminde bunu belirtmek gerekir.


Her programlama dilinde veya sistemde farklılık gösterebilir. Her dillin kendine ait çağırma biçimi olabilir hatta assembly ile istedigimiz biçimde convention oluşturabilir ve kullanabiliriz. Fakat bunların taşınabilir ve farkllı dillerle kullanılabilir olması durumunda standartlara uyma yükümlülüğü vardır. Özetle şu sorulara cevap bulmaya çalışır:

  • Çağrılan fonksiyon hangi yazmaçları bozma hakkına sahiptir, hangi yazmaçları korumak zorundadır?
  • Çağıran fonksiyon ile çağrılan fonksiyon arasında parametre aktarımı nasıl yapılacaktır?
  • Çağrılan fonksiyonun geri dönüş değeri çağrılan fonksiyona nasıl aktarılacaktır?
  • Parametre aktarımı için Stack kullanıldı ise stack'i düzenleme işi kime aittir?


Çağırma biçimi konusu C standartlarını ilgilendiren bir konu değildir. Çünkü C standartları böylesi aşağı seviyeli belirlemeleri derleyicilere bırakmıştır. Dolayısıyla çağırma biçimlerini oluşturmak için gereken anahtar sözcükler derleyicilerde bir eklenti (extension) biçiminde bulunurlar. Çağırma biçimlerine ilişkin anahtar sözcükler genel olarak tür belirten sözcük ile fonksiyon isimlerinin arasına yerleştirilmektedir. Örneğin:

  • Microsoft derleyicilerinde çağırma biçimleri yukarıdaki örnekte olduğu gibi iki alt tire ( __ ) ile başlayan anahtar sözcüklerle temsil edilmektedir. 

void __cdecl foo(int a, int b) {
   
}


  • gcc derleyicilerinde ise fonksiyon özellikleri (function attributes) biçimindeki bir sentaks ile temsil edilir. 

void __attribute__((cdecl)) foo(int a, int b) {
   
}