2016-11-30 178 views
0

在閱讀一本關於機器指令和程序的書時,我遇到了一個特殊的問題,那就是彙編程序掃描整個源程序兩次。它在第一遍/掃描期間構建一個符號表,並在第二次掃描期間將整個程序與它關聯起來。彙編程序需要以類似的方式爲函數提供地址。
現在,由於彙編程序通過了兩次程序,爲什麼需要在可以使用之前聲明一個函數呢?彙編程序不會從第1遍提供函數的地址,然後在第2遍期間將其與程序關聯? 我正在考慮在這種情況下的C編程。程序的彙編和執行 - 兩遍彙編程序

+2

在什麼彙編程序之前,你需要聲明一個函數纔可以使用? –

+4

C編譯器不是彙編器。 C語言的規則與裝配工的工作無關。 –

+0

我的意思是說,要被「組裝」的編譯程序需要對程序包含的每個函數,變量等進行適當的定義。如果彙編程序必須通過程序兩次,那麼不需要宣佈功能是不必要的? –

回答

1

簡單的答案是,C程序要求函數在可以使用之前被聲明,因爲C語言被設計爲一次編譯器處理。它與彙編器和函數的地址沒有任何關係。在使用它之前,編譯器需要知道符號的類型,無論是函數,變量還是別的東西。

考慮一個簡單的例子:

int foo() { return bar(); } 
int (*bar)(); 

爲了生成正確的代碼編譯器需要知道bar不是一個函數,而是指向函數的指針。該代碼僅適用於在foo的定義之前放置extern int (*bar)();,以便編譯器知道bar是什麼類型。

雖然語言理論上可以設計爲要求編譯器使用兩遍,但這需要語言設計上的一些重大改變。要求兩次通過也會增加編譯器所需的複雜性,減少可以託管C編譯器的平臺數量。在C開始開發時,這是非常重要的考慮因素,當64K(65,536)字節的RAM是大量內存時。即使在今天,對大型程序的編譯時間也會有明顯的影響。

請注意,通過支持隱式函數聲明,C語言確實允許你想要什麼。 (在我上面的示例中,foo中的bar之前沒有聲明過)。但是,此功能已過時,受到限制並被認爲是危險的。