爲什麼編譯器在函數調用之前放置瞭如此多的命令(查看下面的鏈接)?據我所知,它應該只在調用之前傳遞函數參數。C++編譯器函數調用
struct A{
int c = 5;
void test(unsigned int a){
a++;
c++;
}
};
struct C{
int k =2;
A a;
};
struct D{
int k =2;
C c;
};
struct B{
int k =2;
D d;
};
void test(unsigned int a){
a++;
}
B *b = new B();
A *ae = new A();
int main()
{
int a = 1;
A ai;
B bi;
C ci;
// 2 operations (why not pop/push ?)
// movl -36(%rbp), %eax
// movl %eax, %edi
// call test(unsigned int)
test(a);
// 4 operations (why 4? we pass something else?)
// movl -36(%rbp), %edx
// leaq -48(%rbp), %rax
// movl %edx, %esi
// movq %rax, %rdi
// call A::test(unsigned int)
ai.test(a);
ae->test(a);
// 5 operations before call (what a hell is going here?, why that "addq" ?)
// movl -36(%rbp), %eax
// leaq -32(%rbp), %rdx
// addq $4, %rdx
// movl %eax, %esi
// movq %rdx, %rdi
// call A::test(unsigned int)
ci.a.test(a);
bi.d.c.a.test(a);
b->d.c.a.test(a);
// no matter how long this chain will be - it will always took 5 operations
}
爲什麼當我們調用類的成員,花了額外的4個命令準備打電話?我們也加載對象地址來註冊?
,並用5個OPS最後一種情況,就是超越我...
附:在我年輕的時候,通常我們會把函數參數放在堆棧中(推),而不是讀取它們(彈出)。現在,我們通過寄存器傳遞參數?
64位調用約定訪問不使用推。 –
@RaymondChen這是什麼?我只與舊的x80 / x86 asm :) – tower120
@Gluttton註冊與q(沒有)/(無法推)到堆棧?它有沒有'pushq'? – tower120