C / C ++ 'da fonksiyon çağrısının yığın çerçevesini anlıyor musunuz?


19

Yığın çerçeveleri nasıl inşa ve hangi değişkenler (params) hangi sırayla yığın itti anlamaya çalışıyorum? Bazı arama sonuçları, C / C ++ derleyicisinin bir işlev içinde gerçekleştirilen işlemlere göre karar verdiğini göstermiştir. Örneğin, işlevin geçirilen int değerini 1 (+ ++ operatörüne benzer) kadar arttırması ve döndürmesi gerekiyorsa, işlevin tüm parametrelerini ve yerel değişkenleri kayıtlara yerleştirirdi.

Hangi kayıtları döndürülen veya değer parametreleri tarafından geçmek için kullanılan merak ediyorum. Referanslar nasıl iade edilir? Derleyici eax, ebx, ecx ve edx arasında nasıl seçim yapar?

İşlev çağrıları sırasında kayıtların, yığın ve yığın referanslarının nasıl kullanıldığını, derlendiğini ve yok edildiğini anlamak için nelere ihtiyacım var?


bunu okumak oldukça zordur (metnin duvarı). Sakıncası var düzenleyebilir daha iyi bir şekle yazınızı ing?
gnat

1
Bu soru benim için oldukça geniş görünüyor. Ayrıca, bu çok platforma özgü olmayacak mı?
Kazark


Yanıtlar:


11

Dirk'in söylediklerine ek olarak, yığın karelerinin önemli bir kullanımı, bir işlev çağrısından sonra geri yüklenebilmeleri için önceki kayıt değerlerini kaydetmektir. Bu nedenle, parametrelerin iletilmesi, bir değer döndürülmesi ve dönüş adresinin kaydedilmesi için kayıtların kullanıldığı işlemcilerde bile, bu kayıtların değerleri, çağrıdan sonra geri yüklenebilmeleri için bir işlev çağrısından önce yığına kaydedilir. Bu, bir işlevin kendi parametrelerinin üzerine yazmadan veya kendi dönüş adresini unutmadan başka birini çağırmasına izin verir.

Bu nedenle, tipik bir "genel" sistemde A işlevinden B işlevini çağırmak aşağıdaki adımları içerebilir:

  • fonksiyon A:
    • dönüş değeri için itme alanı
    • itme parametreleri
    • dönüş adresini it
  • B fonksiyonuna atla
  • fonksiyon B:
    • önceki yığın çerçevesinin adresini zorla
    • bu işlevin kullandığı kayıtların itme değerleri (böylece geri yüklenebilir)
    • yerel değişkenler için itme alanı
    • gerekli hesaplamayı yap
    • kayıtları geri yükle
    • önceki yığın çerçevesini geri yükle
    • işlev sonucunu sakla
    • dönüş adresine atla
  • fonksiyon A:
    • parametreleri patlat
    • dönüş değerini pop

Bu, hiçbir şekilde işlev çağrılarının çalışabileceği tek yol değildir (ve bir veya iki adım bozuk olabilir), ancak işlemcinin iç içe işlev çağrılarını işlemek için yığının nasıl kullanıldığı hakkında bir fikir vermelidir.


Burada "itme" tam olarak ne anlama geliyor? Ne yapacağımı bilmiyorum.
Tomáš Zato - Monica'yı

2
@ TomášZato pushve popbir yığın üzerinde iki temel işlemdir. Yığın, bir kitap yığını gibi, ilk giren ilk çıkar yapısıdır. Siz push, yığının üstüne yeni bir nesne koyuyorsunuz; Ne zaman popsen yığının üstünden bir nesne alıyoruz. Ortaya nesne yerleştirme veya çıkarma izniniz yok, yalnızca yığının üstünde çalışabilirsiniz. Genel olarak yığınlar ve özellikle Wikipedia'daki program yığını hakkında daha fazla bilgi edinebilirsiniz .
Caleb

11

Bu, kullanılan çağrı kuralına bağlıdır. Çağıran sözleşmeyi kim tanımlarsa isterse bu kararı verebilir.

X86'daki en yaygın çağrı kuralında, kayıtlar parametreleri geçmek için kullanılmaz; parametreler en sağdaki parametreden başlayarak yığına itilir. Dönüş değeri eax'a yerleştirilir ve fazladan alana ihtiyaç duyarsa edx'i kullanabilir. Referanslar ve işaretçiler her ikisi de eax adresinde döndürülür.


5

Yığını çok iyi anlarsanız, belleğin programda nasıl çalıştığını anlarsınız ve belleğin programda nasıl çalıştığını anlarsanız, programda fonksiyon deposunun nasıl çalıştığını anlarsınız ve programdaki fonksiyon deposunun nasıl olduğunu anlarsanız, özyinelemeli fonksiyonun nasıl çalıştığını ve özyinelemeli işlevin nasıl çalıştığını anlarsınız, derleyicinin nasıl çalıştığını anlarsınız ve derleyicinin nasıl çalıştığını anlarsanız zihniniz derleyici olarak çalışır ve herhangi bir programı çok kolay hata ayıklarsınız

Yığın nasıl çalıştığını açıklayayım:

İlk önce yığında nasıl fonksiyon deposu olduğunu bilmek zorundasınız:

Yığın deposu dinamik bellek ayırma değerleri. Yığın deposu otomatik ayırma ve silme değerleri.

resim açıklamasını buraya girin

Örnekle anlayalım:

def hello(x):
    if x==1:
        return "op"
    else:
        u=1
        e=12
        s=hello(x-1)
        e+=1
        print(s)
        print(x)
        u+=1
    return e

hello(4)

Şimdi bu programın bölümlerini anlayın:

resim açıklamasını buraya girin

Şimdi yığının ne olduğunu ve yığın parçalarının neler olduğunu görelim:

resim açıklamasını buraya girin

Yığın tahsisi:

Herhangi bir fonksiyonun tüm yerel değişkenlerini yüklemesine bakılmaksızın “dönüş” alırsa veya yığın çerçevesinden derhal yığından döneceği herhangi bir şeyi hatırlayın. Bu, herhangi bir özyinelemeli işlev temel koşulu aldığında ve temel koşuldan sonra dönüşü koyduğumuzda, temel koşulun programın “başka” bölümünde yer alan yerel değişkenleri yüklemek için beklemeyeceği anlamına gelir ve geçerli kareyi yığından hemen döndürür ve şimdi bir kare varsa sonraki kareye dön etkinleştirme kaydında. Bunu pratikte görün:

resim açıklamasını buraya girin

Bloğun yeniden yerleştirilmesi:

Şimdi bir işlev geri dönüş ifadesi bulduğunda mevcut kareyi yığından siler.

yığın değerinden döndürülürken, yığın içinde tahsis edildikleri sıralamanın tersi sırasına göre döndürülür.

resim açıklamasını buraya girin

Bunlar çok kısa bir açıklama ve yığın ve çift özyineleme hakkında daha derin bilmek istiyorsanız bu blogun iki gönderisini okuyun:

Adım adım yığın hakkında daha fazla bilgi

Yığınla adım adım Çift özyineleme hakkında daha fazla bilgi


3

Aradığınıza Uygulama İkili Arabirimi denir - ABI .

Her derleyici için ABI'yı belirten bir özellik vardır.

Her platform, derleyiciler arasında birlikte çalışabilirliği desteklemek için genellikle ve ABI'yi belirtir. Örneğin, x86 Arama Kuralları , x86 ve x86-64 için tipik arama kurallarını belirtir. Ancak wikipedia'dan daha resmi bir belge bekliyorum.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.