2009-08-18 17 views
6

C++ sınıf yöntemi çağrıldığında, örtülü 'this' işaretçisi ilk argüman mı, yoksa son mu? yani: ister birinci, isterse sonuncu yığına itilir olsun. olur ++ da G olmadığını cevap olacağını, daha da önemlisiC++ bunu örtüyor ve tam olarak yığında itiliyor nasıl

int foo::bar(foo *const this, int arg1, int arg2); 
//or: 
int foo::bar(int arg1, int arg2, foo *const this); 
dolayısıyla uzantısı olarak

ve: Başka bir deyişle

, ben olmak derleyici tarafından alınır, bir sınıf yöntemi çağrılan olup olmadığını soruyorum Sırasıyla bu işaretçiyi en son veya ilk olarak itin. Google'ı sorguladım, ama fazla bir şey bulamadım.

Ve bir yan not olarak, C++ işlevleri çağrıldığında, C işlevleri ile aynı şeyi yapar mı? i.e:

push ebp 
mov ebp, esp 

Sonuç olarak: bir sınıf yöntemi çağrılmalı mı?

; About to call foo::bar. 
push dword 0xDEADBEEF 
push dword 0x2BADBABE 
push dword 0x2454ABCD ; This one is the this ptr for the example. 
; this code example would match up if the this ptr is the first argument. 
call _ZN3foo3barEpjj 

sayesinde ve çok mecbur.

DÜZENLEME: Ben Bu derleyici çağrı kongre ve hedef mimarisi bağlıdır 4.3

+0

Bu soruyu sormamanız ve derleyiciniz tarafından oluşturulan derleme konusuna bakmak sizin için daha çabuk olurdu. Hepsi, çıkış montaj koduna metin olarak geçiş yapar. –

cevap

15

++ GCC/G kullanıyorum şeyi açıklığa kavuşturmak.

Varsayılan olarak, Visual C++ bunu yığın üzerinde zorlamaz. X86 için derleyici "thiscall" çağırma kuralı için varsayılan olacak ve bunu ecx kaydında geçirecektir. Üye işlevi için __stdcall belirtirseniz, ilk parametre olarak yığının üzerine ittirilir.

VC++ üzerinde x64 için, ilk dört parametre kayıtlara geçirilir. Bu ilk parametre ve rcx kaydında geçti. Raymond Chen, birkaç yıl önce kongre çağrıları konusunda bir dizi bir seriye sahipti. İşte x86 ve x64 makaleleri.

+0

http://en.wikipedia.org/wiki/X86_calling_conventions – Havenard

+0

Teşekkürler. Raymond Chen'den yazı benim için temizledi. Herşey gönlünce olsun. –

1

Bu tür bir ayrıntı C++ standardı tarafından belirtilmemiş. Ancak, gcc (ve C++ ABI'yi izleyen diğer C++ derleyicileri) için C++ ABI'u okuyun.

8

Bu kayıtta geçirilen ilk parametre olarak this davranır hiçbir iyileştirme ayarlarıyla Linux üzerinde 4.1.2 ++ G derleyici ve mimarisine bağlıdır, ancak: Ana ait

class A 
{ 
public: 
    void Hello(int, int) {} 
}; 

void Hello(A *a, int, int) {} 

int main() 
{ 
    A a; 
    Hello(&a, 0, 0); 
    a.Hello(0, 0); 
    return 0; 
} 

Demontaj() :

movl $0, 8(%esp) 
movl $0, 4(%esp) 
leal -5(%ebp), %eax 
movl %eax, (%esp) 
call _Z5HelloP1Aii 

movl $0, 8(%esp) 
movl $0, 4(%esp) 
leal -5(%ebp), %eax 
movl %eax, (%esp) 
call _ZN1A5HelloEii 
+0

Teşekkürler.Bu da son derece yararlı oldu. –

2

sadece (2003 ANSI ISO IEC 14882) bölüm 9.3.2 "Bu işaretçi" C++ Standardının bir okuma vardı ve bunun meydana gereken yerde hakkında bir şey belirtmek görünmüyor argümanlar listesi, bu yüzden bireysel derleyiciye kalmış.

Montaj kodunu oluşturmak için '-S' bayrağını kullanarak gcc ile bazı kodları derlemeye çalışın ve ne yaptığına bakın.

+2

Ayrıca, argümanların yığında mı yoksa tek bir yığın olsa bile mi gideceğini belirtmez. – MSalters