我的理解是静态编译时,因为C语言是过程性语言只能静态联编不能动态联编,而C++编译于此类似,所以是编译时完全。不知道这样对不对?
欢迎选择我的课程,让我们一起见证您的进步~~
入棧的順序是編譯時決定的。
函數呼叫之前需要入棧的主要是函數參數,而參數都是固定的(可變參數只是用巨集確定偏移量)。 呼叫函數的程式碼是放在程式碼段的,入棧都是以指令方式進行的,所以順序都是編譯時決定的。
@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 }
不懂彙編也沒關係,在編譯過程中,參數的傳遞順序,參數、本地變數等應該放在堆疊的哪個位置(相對位置)都是定了的。當程式運行到對應程式後會按照編譯好的順序對堆疊進行操作。
入棧這個不是運作時才有的過程嗎?編譯只是翻譯為字節碼的過程,為什麼會有入棧?
入棧的順序是編譯時決定的。
函數呼叫之前需要入棧的主要是函數參數,而參數都是固定的(可變參數只是用巨集確定偏移量)。
呼叫函數的程式碼是放在程式碼段的,入棧都是以指令方式進行的,所以順序都是編譯時決定的。
@lianera 說的不錯,入棧的順序是編譯時決定的。
我這給你看個例子:
我有段程式碼是這樣的
編譯後,他的彙編程式碼是這樣的
不懂彙編也沒關係,在編譯過程中,參數的傳遞順序,參數、本地變數等應該放在堆疊的哪個位置(相對位置)都是定了的。當程式運行到對應程式後會按照編譯好的順序對堆疊進行操作。
入棧這個不是運作時才有的過程嗎?編譯只是翻譯為字節碼的過程,為什麼會有入棧?