我的理解是靜態(tài)編譯時,因為C語言是過程性語言只能靜態(tài)聯(lián)編不能動態(tài)聯(lián)編,而C++編譯于此類似,所以是編譯時完全。不知道這樣對不對?
歡迎選擇我的課程,讓我們一起見證您的進步~~
入棧的順序是編譯時決定的。
函數(shù)呼叫之前需要入棧的主要是函數(shù)參數(shù),而參數(shù)都是固定的(可變參數(shù)只是用巨集確定偏移量)。
呼叫函數(shù)的程式碼是放在程式碼段的,入棧都是以指令方式進行的,所以順序都是編譯時決定的。
@lianera 說的不錯,入棧的順序是編譯時決定的。
我這給你看個例子:
我有段程式碼是這樣的
#include <stdio.h>
int test_fun(int a, int b)
{
return a + b;
}
int main(int argc, char *argv[])
{
int A, B, ret;
A = 3;
B = 4;
ret = test_fun(A, B);
return 1;
}
編譯後,他的彙編程式碼是這樣的
int test_fun(int a, int b)
{
400474: 55 push %rbp
400475: 48 89 e5 mov %rsp,%rbp
// $edi存的是A的值,$esi存的是B的值,將他們壓入棧中
400478: 89 7d fc mov %edi,-0x4(%rbp)
40047b: 89 75 f8 mov %esi,-0x8(%rbp)
return a + b;
40047e: 8b 45 f8 mov -0x8(%rbp),%eax
400481: 8b 55 fc mov -0x4(%rbp),%edx
400484: 8d 04 02 lea (%rdx,%rax,1),%eax
}
int main(int argc, char *argv[])
{
400489: 55 push %rbp
40048a: 48 89 e5 mov %rsp,%rbp
40048d: 48 83 ec 20 sub rrreeex20,%rsp
400491: 89 7d ec mov %edi,-0x14(%rbp)
400494: 48 89 75 e0 mov %rsi,-0x20(%rbp)
int A, B, ret;
// 壓入本地變量A
A = 3;
400498: c7 45 f4 03 00 00 00 movl rrreeex3,-0xc(%rbp)
// 壓入本地變量B
B = 4;
40049f: c7 45 f8 04 00 00 00 movl rrreeex4,-0x8(%rbp)
ret = test_fun(A, B);
4004a6: 8b 55 f8 mov -0x8(%rbp),%edx
4004a9: 8b 45 f4 mov -0xc(%rbp),%eax
// 將A和B的值放入相應的寄存器
4004ac: 89 d6 mov %edx,%esi
4004ae: 89 c7 mov %eax,%edi
// 調用test_fun
4004b0: e8 bf ff ff ff callq 400474 <test_fun>
4004b5: 89 45 fc mov %eax,-0x4(%rbp)
return 1;
4004b8: b8 01 00 00 00 mov rrreeex1,%eax
}
不懂彙編也沒關係,在編譯過程中,參數(shù)的傳遞順序,參數(shù)、本地變數(shù)等應該放在堆疊的哪個位置(相對位置)都是定了的。當程式運行到對應程式後會按照編譯好的順序對堆疊進行操作。