主要介紹一些操做系統的基本知識,須要忘了 設備驅動、操做系統、虛擬空間、物理空間、頁映射、線程等基本概念的建議要回顧下。linux
使用gcc編譯程序生成目標文件中,經歷了四個過程:預處理、編譯、彙編、連接windows
預編譯:處理源代碼文件中以「#」開頭的與編譯指令(生成 .i 文件)函數
編譯:對預處理後的文件進行詞法分析、語法分析、語義分析及優化,產生相應的彙編代碼文件(生成 .s 文件)優化
(gcc把預編譯和編譯合成一個步驟,使用cc1程序完成,改程序位於 /usr/lib/gcc/x86_64-linux-gnu/4.7/ 中)操作系統
彙編:將彙編代碼轉成機器可執行的指令,每個彙編語句幾乎對應着一條機器指令(使用匯編器 as 完成,生成 .o 目標文件)線程
連接:連接須要用到的其餘文件,生成最終可執行文件(使用ld程序,生成 .out 文件)(其過程包括地址和空間分配、符號決議、重定位)調試
可執行文件格式:PE(windows下的Portable Executable)、ELF(linux下的 Executable Linkable Format),都是COFF(Common file firmat)格式的變種orm
動態連接庫(DLL,Dynamic Linking Library,windows下的.dll和linux下的.so)和靜態連接文庫(Static Linking Library,windows下的的.lib和linux下的.a)文件已可執行文件格式存儲。對象
linux下可用 file 指令查看文件格式接口
ELF文件結構:代碼段、數據段、BSS段、文件頭、段表、重定位表、字符串表、符號表、調試表
空間與地址分配、符號解析和重定位
由於基於Linux開發,windows相關的暫時跳過
操做系統裝載程序到內存:覆蓋裝入和頁映射
靜態連接會浪費內存和磁盤空間、模塊更新困難
靜態連接是連接時重定位,動態連接是裝載時重定位
地址無關代碼(PIC):解決共享對象指令中對絕對地址的重定位問題
延遲綁定(PLT):當函數第一次被調用時才進行綁定
ldd:查看程序依賴庫
readelf:查看ELF結構相關信息
objdump:打印對象信息
共享庫版本命名:libname.so.x.y.z(主版本號x(重大升級,不兼容其餘版本),次版本號y(增量升級),發佈版本號z(修正、改進))
SO-NAME:只保留主版本號的共享庫名
連接名:即libname.so.x.y.z中的name
LD_LIBRARY_PATH:改變某程序的共享庫查找路徑
LD_PRELOAD:指定預先裝載的一些共享庫或目標文件
LD_DEBUG:打開動態連接器的調試功能
跳過
調用慣例:約定的函數調用方式
程序運行步驟:操做系統建立進程,把控制權交給程序入口(通常是運行庫中某個入口函數);入口函數對運行庫和運行環境進行初始化,包括堆、I/O、線程、全局變量構造等;入口函數完成初始化後,調用main函數,執行程序主體部分;main函數執行完畢後,返回入口函數,進行清理工做,包括全局變量析構、堆銷燬、關閉I/O等,而後進行系統調用結束進程
線程私有存儲空間:棧、線程局部存儲、寄存器
CRT(C語言運行庫):啓動與退出、標準函數、I/O、堆、語言實現、調試
系統調用:應用程序與操做系統內核之間的接口
主要講 Mini CRT的實現