Aracılığıyla paylaş


x64 yığın kullanımı

RSP'nin mevcut adresini aşan tüm bellek değişken bellek olarak kabul edilir: İşletim sistemi veya hata ayıklayıcı, bir kullanıcı hata ayıklama oturumu sırasında veya kesme işleyicisi çalışırken bu bellek üzerinde değişiklik yapabilir. Bu nedenle, değerleri bir yığın çerçevesine okumaya veya yazmaya çalışmadan önce RSP her zaman ayarlanmalıdır.

Bu bölümde, yerel değişkenler ve alloca intrinsiği için yığın alanının tahsisi ele alınmaktadır.

Yığın tahsisi

İşlevin prologu yerel değişkenler, kaydedilmiş yazmaçlar, yığın parametreleri ve yazmaç parametreleri için yığın alanı ayırmadan sorumludur.

Parametre alanı her zaman yığının en altındadır (kullanılsa alloca bile), böylece herhangi bir işlev çağrısı sırasında her zaman dönüş adresine bitişik olur. En az dört girdi içerir, ancak çağrılabilecek herhangi bir işlevin ihtiyaç duyduğu tüm parametreleri tutmak için her zaman yeterli alan içerir. Parametrelerin kendileri hiçbir zaman yığına yerleşmese bile, yazmaç parametreleri için her zaman alan ayrıldığını aklınızda bulundurun; çağrılan, tüm parametreleri için alan ayrıldığının garantisini alır. Ev adresleri, yazmaç içindeki bağımsız değişkenler için gereklidir, böylece çağrılan fonksiyonun bağımsız değişken listesinin (va_list) veya bireysel bir bağımsız değişkenin adresini alması gerektiğinde bitişik bir alan kullanılabilir duruma gelir. Bu alan ayrıca, thunk yürütme sırasında ve hata ayıklama seçeneği olarak yazmaç argümanlarını kaydetmek için uygun bir yer sağlar (örneğin, prolog kodunda ev adreslerinde depolanmışlarsa, hata ayıklama sırasında argümanların bulunmasını kolaylaştırır). Çağrılan işlevin 4'ten az parametresi olsa bile, bu 4 yığın konumu etkin bir şekilde çağrılan işleve aittir ve parametre kayıt değerlerini kaydetmenin yanı sıra çağrılan işlev tarafından başka amaçlarla kullanılabilir. Bu nedenle, çağıran bir işlev çağrısı sırasında bu yığın bölgesine bilgi kaydedemez.

Bir işlevde alan dinamik olarak ayrılmışsa (alloca), kalıcı olmayan bir yazmaç yığının sabit bölümünün tabanını işaretlemek için çerçeve işaretçisi olarak kullanılmalıdır ve bu kayıt prologa kaydedilip başlatılmalıdır. alloca Kullanıldığında, aynı arayandan gelen çağrıların kayıt parametreleri için farklı giriş adresleri olabileceğini unutmayın.

Yığın her zaman 16 bayt hizalı olarak korunur, ancak prolog içinde (örneğin, dönüş adresi gönderildikten sonra) ve belirli bir çerçeve işlev sınıfı için Function Types'ta belirtilen durumlar dışında.

Aşağıda, A fonksiyonunun yaprak olmayan B fonksiyonunu çağırdığı yığın düzenine örnek verilmiştir. A fonksiyonunun prologu, yığının alt kısmında B tarafından gerekli olan tüm yazmaç ve yığın parametreleri için zaten alan ayırmıştır. Çağrı dönüş adresini yönlendirir ve B'nin giriş bölümü yerel değişkenleri, geçici olmayan yazmaçlar ve işlevleri çağırmak için gereken alan için alan ayırır. B kullanıyorsa alloca, alan yerel değişken/kalıcı olmayan yazmaç kaydetme alanı ile parametre yığını alanı arasında ayrılır.

x64 dönüştürme örneği için yığın düzeninin diyagramı.

B işlevi başka bir işlevi çağırdığında, dönüş adresi RCX giriş adresinin hemen altına gönderiliyor.

Dinamik parametre yığın alanı yapısı

Bir çerçeve işaretçisi kullanılırsa, parametre yığını alanını dinamik olarak oluşturmak için seçeneği vardır. Bu işlem şu anda x64 derleyicisinde yapılmaz.

İşlev türleri

Temelde iki işlev türü vardır. Yığın çerçevesi gerektiren bir işlev, çerçeve işlevi olarak adlandırılır. Yığın çerçevesi gerektirmeyen bir işleve yaprak işlev adı verilir.

Çerçeve işlevi, yığın alanı ayıran, diğer işlevleri çağıran, kalıcı olmayan kayıtları kaydeden veya özel durum işlemeyi kullanan bir işlevdir. Ayrıca bir işlev tablosu girişi gerektirir. Çerçeve işlevi bir prolog ve bir epilog gerektirir. Çerçeve işlevi, yığın alanını dinamik olarak ayırabilir ve bir çerçeve işaretçisi kullanabilir. Çerçeve işlevi, bu çağrı standardının tüm özelliklerine sahiptir.

Çerçeve işlevi başka bir işlevi çağırmazsa yığını hizalamak gerekli değildir (Bölüm Yığını Ayırma'da başvurulur).

Yaprak işlev, işlev tablosu girişi gerektirmeyen işlevdir. RSP de dahil olmak üzere geçici olmayan kayıtlarda değişiklik yapamaz; başka bir deyişle herhangi bir işlevi çağıramaz veya yığın alanı ayıramaz. Yürütürken yığını hizalanmamış olarak bırakmasına izin verilir.

malloc hizalaması

malloc'un , temel hizalaması olan ve ayrılan bellek miktarına sığabilecek herhangi bir nesneyi depolamak için uygun şekilde hizalanmış belleği döndürmesi garanti edilir. Temel hizalama, hizalama belirtimi olmadan uygulama tarafından desteklenen en büyük hizalamadan küçük veya buna eşit bir hizalamadır. (Microsoft C++'da, double için gereken hizalama 8 bayttır. 64 bit platformları hedefleyen kodda ise hizalama 16 bayttır.) Örneğin, dört baytlık bir tahsis, dört baytlık veya daha küçük herhangi bir nesneyi barındıran bir sınıra hizalanır.

Visual C++, fazla hizalanmış olarak da bilinen genişletilmiş hizalamalı türlere izin verir. Örneğin, SSE türleri __m128 ve __m256, ve n 8'den büyük olduğunda __declspec(align( n )) kullanılarak bildirilen türlerin genişletilmiş hizalaması vardır. Genişletilmiş hizalama gerektiren bir nesne için, uygun bir sınırdaki bellek hizalaması malloc tarafından garanti edilmemektedir. Fazla hizalanmış türler için bellek ayırmak için _aligned_malloc ve ilgili işlevleri kullanın.

alloca

_alloca'nın 16 bayt hizalı olması ve ek olarak bir çerçeve işaretçisi kullanması gerektirir.

Yığın Ayırma'da açıklandığı gibi, ayrılan yığının sonraki işlevlere ait parametreler için ondan sonra alan içermesi gerekir.

Ayrıca bkz.

x64 yazılım kuralları
hizalamak
__declspec