2011-09-12 14 views
18

Sadece x64 montajını öğrenmeye başladım ve fonksiyonlar, argümanlar ve yığın hakkında bir sorum var. Anladığım kadarıyla, bir fonksiyondaki ilk dört argüman, Windows'da rcx, rdx, r8 ve r9 kayıtlarına (ve floatlar için xmm0-xmm3) geçiyor. Yani dört parametre olur ile önemsiz bir ekleme fonksiyonu şuna benzer: AncakDört argümandan daha az işlevler için yığın alanı ayırıyor mu?

add: 
    mov r10, rcx 
    add r10, rdx 
    add r10, r8 
    add r10, r9 
    mov rax, r10 
    ret 

, ben documentation that mentions this rastladım: En azından

, her fonksiyon 32 bayt ayırmak gerekir (dört 64- yığındaki bit değerleri). Bu alan, yazmaçların iyi bilinen bir yığın konumuna kolayca kopyalanabilmesi için işleve geçirilmesini sağlar. Callee işlevi, giriş registerı param'lerini yığına dökmek için gerekli değildir, ancak yığın alanı rezervasyonu gerektiğinde bunu sağlar.

Yani, yapıyorum işlevler dört parametre veya daha az almak bile ben yığın yer ayırtmak gerekiyor, ya da sadece bir öneridir?

+1

http://www.agner.org/: Örneğin GetAsyncKeyState ilk iki talimatlar parametreler için kullanmak Aranan için rezerve zannediyorsunuz 0x20 bayt alanında dönüş değeri yukarıda yığını üzerine optimize et/optimizing_assembly.pdf bölüm 4'te * her zaman * yer ayırmanız gerektiğini belirten bir örnek var. – user786653

+1

Lanet, düzenlemek için çok geç. [oldnewthing] (http://blogs.msdn.com/b/oldnewthing/archive/2004/01/14/58579.aspx) amd64 arama kuralı üzerine blog girişi. – user786653

+0

Sizin için yapbozun bir başka parçası: bir *** yaprak işleviniz var ***, yani başka işlevler çağırmıyor. – jww

cevap

13

Teklifiniz, belgelerin "çağrı kuralı" bölümünden alınmıştır. En azından, montaj kodunuzdan başka işlevleri çağırmazsanız, bunun için endişelenmenize gerek yoktur. Eğer öyleyse, diğer şeylerin yanı sıra, "kırmızı bölge" ve yığın hizalama hususlarına saygı göstermelisiniz, alıntı yaptığınız tavsiyenin sağlaması amaçlanmıştır.

DÜZENLEME: this post "kırmızı bölge" ve "gölge alanı" arasındaki farkı açıklar.

+0

Sistem V belgelerinde kullanılan "kırmızı bölge" yi gördüm, ancak Windows belgeleri "gölge alanı" kullanıyor. Bunlar aynı şey mi? Eğer kimse bilmiyorsa, başka bir soru soracağım. –

+0

Kısmen kendime yanıt: hayır, "kırmızı bölge" ve "gölge alanı" aynı şey değil. "Gölge alanı", yığında ayrılmış 32 baytın adıdır. Arayan tarafından rezerve edildi, bu yüzden normal ABI ile callable olmak istediğinizde isteğe bağlı değildir, ancak bunun için endişelenmenize gerek yok. –

+0

Yani yukarıdaki kod örneği "uygun", 'sub rsp, 32' başlığına eklemek ve 'rsp, 32' sonuna kadar eklemek için yapmak zorundayım? – Don

0

Sadece bilmeden bu koştu ve onu durum gibi görünüyor.

user32.GetAsyncKeyState - mov [rsp+08],rbx 
user32.GetAsyncKeyState+5- mov [rsp+10],rsi 
user32.GetAsyncKeyState+A- push rdi 
user32.GetAsyncKeyState+B- sub rsp,20 
İlgili konular