编译相关
編譯的過程 :
1. 詞法分析,程序被掃描成:關鍵字,標識符,字面量和特殊符號這些記號。
2. 語法分析,對記號進行語法分析產生語法樹。(代碼最終由表達式組合)
3. 語義分析,經過類型匹配和轉換,把語法樹上的表達式都標識上類型。
4. 運行時無關的中間碼的生成,此時的語法樹可以轉換成三址碼,并進行初步優化。
5. 生成目標代碼,但此時變量的地址并未確定。
?
目標文件的內容: 段里放的都是真正的東西,比如指令,變量值。至于名稱都在符號表里,所以.bss段沒有內容。 符號表里列舉出了所有的符號,以及那些符號對應的值或指令在哪。 在鏈接中用到的符號主要是函數名和變量名,而且是經過修飾的(C和C++的修飾不一樣,注意extern "C")。 需要重定位的地方會被記錄到重定位段里。
?
鏈接的背景: 程序經常改變,于是指令和變量的地址就會跟著改變,導致跳轉指令也要跟著調整。 于是人們用符號標識位置,并在每次匯編的時候都重新計算符號的地址,然后統一填入。 獨立編譯模塊變得流行,需要解決變量和函數的跨模塊訪問問題。
?
鏈接的過程:
1. 掃描所有的輸入目標文件,合并相同段,分配地址空間,收集全局符號表。這一步后,所有符號都有了地址。
2. 讀取重定位信息,調整代碼地址。
?
常常在我腦子中轉的一個問題是:context switch是哪個程序?當系統中運行一個shell,然后由shell調用hello,那個執行context switch的system call是算哪個程序?答案是:那個system call對應的那一串執行context switch的指令不是程序。程序是在操作系統之上的概念,當指令落入操作系統手中,就不是程序的概念了。如果要考慮context switch層面上的問題,計算機工作過程就不應該看成是進程切換的過程,而是單一的一維指令執行的過程,在那個層面上,沒有進程的概念,只有指令周期和有限狀態機的概念。
?
理解這個過程值得注意的點有:context switch對于進程來說是透明的,fork()函數也只是一個函數而已,它并不負責那個新進程是怎么創建的,它只管執行一下這條指令然后收結果,在它看來結果是立即收到的,并沒有等“很多有關創建一個新進程的指令執行”再收到結果,因為那些都是它本身進程外的事情。收到結果,如果結果是0表示那個“任務”成功完成了,如果是其它的,表示那個“任務”沒有完成,至于那個“任務”是什么,它并不在乎。
?
于是,我需要重新思考什么是操作系統,它給應用程序提供了怎么樣一個平臺,它提供的系統調用接口是怎么樣的,我需要了解清楚操作系統的全貌,才能在編程的工作中游刃有余。要知道,當計算正在執行一條指令時,這條指令要么來自應用程序,要么來自操作系統,我需要知道,哪些是操作系統份內的事情,哪些是應用程序份內的事情。
?
?
?
?
轉載于:https://www.cnblogs.com/caicaiandtutu/archive/2012/07/08/2581500.html
總結
- 上一篇: 双向链表的快速排序
- 下一篇: 别说我不会玩,我来告诉你iPhone有多