A. linux學習書籍求推薦
Linux學習書籍求推薦
1、《Linux與Unix Shell 編程指南》
C語言基礎
1、《C Primer Plus,5th Edition》【美】Stephen Prata著
2、《The C Programming Language, 2nd Edition》【美】Brian W. Kernighan David M. Rithie(K & R)著
3、《Advanced Programming in the UNIX Environment,2nd Edition》(APUE)
4、《嵌入式Linux應用程序開發詳解》
Linux內核
1、《深入理解Linux內核》(第三版)
2、《Linux內核源代碼情景分析》毛德操 胡希明著
研發方向
1、《UNIX Network Programming》(UNP)
2、《TCP/IP詳解》
3、《Linux內核編程》
4、《Linux設備驅動開發》(LDD)
硬體基礎
1、《ARM體系結構與編程》杜春雷著
2、S3C2410 Datasheet
英語基礎
1、《計算機與通信專業英語》
系統教程
1、《嵌入式系統――體系結構、編程與設計》
2、《嵌入式系統――採用公開源代碼和StrongARM/Xscale處理器》毛德操 胡希明著
3、《Building Embedded Linux Systems》
理論基礎
1、《演算法導論》
2、《數據結構(C語言版)》
3、《計算機組織與體系結構?性能分析》
4、《深入理解計算機系統》【美】Randal E. Bryant David O』Hallaron著
5、《操作系統:精髓與設計原理》
6、《編譯原理》
7、《數據通信與計算機網路》
8、《數據壓縮原理與應用》
入門篇
《LINUX權威指南》書不錯,寫的很全面也比較廣,涉及的不深,做為入門書籍不錯,可以比較全面的了解linux 。另外比較熱門的也可以看看《鳥哥的私房菜》等書,偏管理類的書。如果想做server方向的可以找來看看。
驅動 篇
《LINUX設備驅動程序 》就是網上說的「LDD」,經典之作,必備書籍。國產經典《Linux驅動詳細解》也是一本非常不錯的書,很實用,書中源代碼分析比較多,基於2440的,對linux外圍驅動有很全面的講解
內核篇
浙江大學的《LINUX內核源代碼情景分析》,外國鬼子的《萊昂氏UNIX源代碼分析》還有《深入理解linux內核》都是出名的經典巨作。另外趙 炯的《LINUX內核完全剖析–基於0.12內核》也非常不錯,對內核代碼進行了詳細的注釋,非常有助於對內核的理解和代碼的分析。
shell篇
《LINUX與UNIX Shell編程指南》
應用 編程
不用說了肯定是《unix環境高級編程》被稱為unix編程的聖經。
TCP/IP篇
《TCP/IP詳解》作者W.Richard Stevens也是《unix環境高級編程》的作者,牛人出的書沒有一本不是經典的。但是英年早逝,默哀一下。
c語言
《The C Programming Language》正是作者造出來的c語言,書能垃圾就怪了
《c和指針》和《c缺陷和陷阱》兩本必備。包含了c語言最容易出錯的地方,加深c語言功力的好材料。
關於演算法
《演算法導論》
1 熟悉linux基本環境 >>> 《鳥哥的私訪菜》《unix初級教程》 《linux編程寶典》(市面上無,圖書館有), 等等。
2 熟悉操作系統的基礎知識 >>> 《現代操作系統》 《操作系統概念》
3 熟悉系統編程 >>> 《unix環境高級編程第二版》《unix操作系統設計與實現》
4 內核 按先後順序: 《 linux內核設計與實現》 《linux設備驅動程序》 《深入理解 linux內核》 《linux內核源代碼情景分析》 《深入理解linux虛擬內存系統》
5 其他一些書籍: 《freebsd操作系統設計與實現》 《solaris內核結構》 《unix高級教程:系統技術內幕》 《現代體系結構的unix系統:內核程序員的smp與cache技術》 《保護方式下的80386及其編程》 (後3本市面上沒了,大學圖書館里一般都有》 《Intel64 and IA-32 Arichitectures Software Developer』s Manual》
6 其實內核玩深了,體系和編譯也要學好 《計算機體系結構:量化研究方法》 《編譯原理》(龍書)
Linux編程推薦書籍一覽表
shell 編程
《LINUX與UNIX SHELL編程指南》
BASH寶典:
Advanced Bash Scripting Guide (如果你使用的是 GNU/Debian 系統,可以用 apt-get install abs-guide 安裝該文檔)
BASH Programming – Introction HOW-TO
Bash Man
用戶級編程書籍:
Advanced Programming in the UNIX Environment(中文版《UNIX環境高級編程》第二版) 作者 W.Richard
Stevens/尤晉元等
GNU/Linux編程指南 作者 Kurt Wall
Linux 程序設計權威指南 作者 於明儉、陳向陽、方漢
《The Art of Unix Programming》作者 E.S.R
Computer Systems A Programmer』s Perspective
(中文名)《深入理解計算機系統(修訂版)》
《Unix Systems Programming》(中文版《UNIX系統編程》)作者: (美)KAY
A.ROBBINS, STEVE ROBBINS 譯者:陳涓 趙振平
網路編程:
Unix Network Programming V1 & V2,Unix網路編程卷1、2 作者 W.Richard Stevens
《unix網路編程》
XWindow編程
Definitive Guides to the X WindowSystem 作者 Dan Heller, Paula M. Ferguson
內核源代碼閱讀(結合源代碼)和編程
(入門)
《邊干邊學Linux內核指導》
(高級)
《Linux Kernel Development》
《Linux內核源代碼情景分析》
《深入分析Linux內核源代碼》 陳莉君
《 Understanding Linux Network Internals 》即《 深入理解Linux網路內幕(英文影印版)》Christian Benvenuti
內核模塊編程
《The Linux Kernel Mole Programming Guide》
Linux設備驅動編程
Linux設備驅動程序/Linux Device
Drivers 作者 Alessandro Ruibini
多線程編程
《多線程編程指南》
B. 為什麼要學習編譯原理(轉)
大學課程為什麼要開設編譯原理呢?這門課程關注的是編譯器方面的產生原理和技術問題,似乎和計算機的基礎領域不沾邊,可是編譯原理卻一直作為大學本科的必修課程,同時也成為了研究生入學考試的必考內容。編譯原理及技術從本質上來講就是一個演算法問題而已,當然由於這個問題十分復雜,其解決演算法也相對復雜。我們學的數據結構與演算法分析也是講演算法的,不過講的基礎演算法,換句話說講的是演算法導論,而編譯原理這門課程講的就是比較專註解決一種的演算法了。在20世紀50年代,編譯器的編寫一直被認為是十分困難的事情,第一Fortran的編譯器據說花了18年的時間才完成。在人們嘗試編寫編譯器的同時,誕生了許多跟編譯相關的理論和技術,而這些理論和技術比一個實際的編譯器本身價值更大。就猶如數學家們在解決著名的哥德巴赫猜想一樣,雖然沒有最終解決問題,但是其間誕生不少名著的相關數論。 推薦參考書 雖然編譯理論發展到今天,已經有了比較成熟的部分,但是作為一個大學生來說,要自己寫出一個像TurbocC,java那樣的編譯器來說還是太難了。不僅寫編譯器困難,學習悶數編譯原理這門課程也比較困難。 第一本書的原名叫《CompilersPrinciples,Techniques,andTools》,另外一個響亮的名字就是龍書。原因是這本書的封面上有條紅色的龍,也因為獗臼樵詒嘁朐?砘?嘴域確實?忻?所以很多國外的學者都直接取名為龍書。最近機械工業出版社已經出版了此書的中文版,名字就叫《編譯原理》。該書出的比較早,大概是在85或86年編寫完成的,作者之一還是著名的貝爾實驗室的科學家。裡面講解的核心編譯原理至今都沒有變過,所以一直到今天,它的價值都非凡。這本書最大的特點就是一開始就通過一個實際的小例子,把編譯原理的大致內容羅列出來,讓很多編譯螞罩首原理的初學者很快心裡有了個底,也知道為什麼會有這些理論,怎麼運用這些理論。而這一點是我感覺國內的教材缺乏的東西,所以國內的教材都不是寫給願意自學的讀者,總之讓人看了半天,卻不知道裡面的東西有什麼用。 第二本書的原名叫《ModernCompilerDesign》,中文名字叫做《現代編譯程序設計》。該書由人民郵電出版社所出。此書比較關注的是編譯原理的實踐,書中給出了不少的實際程序代碼,還有很多實際的編譯技術問題等等。此書另外一個特點就是其現代而字。在傳統的編譯原理教材中,你是不可能看到如同Java中的垃圾回收等演算法的。因為Java這樣的解釋執行語言是在近幾年才流行起來的東西。如果你想深入學習編譯原理的理論知識,那麼你肯定得看前面那本龍書,如果你想自己動手做一個先進的編譯器,那麼你得看這本《現代編譯程序設計》。 第三本書就是很多國內的編譯原理學者都推薦的那本《編譯原理及實踐》。或許是這本書引入國內比較早吧,我記得我是在高中就買了這本書,不過也是在前段時間才把整本書看完。此書作為入門教程也的確是個不錯的選擇。書中給出的編譯原理講解也相當細致,雖然不如前面的龍書那麼深入,但是很多地方都是點到為止,作為大學本科教學已經是十分深入了。該書的特點就是注重實踐,不過感覺還不如前面那本《現代編譯程序設計》的實踐味道更重。此書的重點還是在原理上的實踐,而非前面那本那樣的技術實踐。《編譯原理及實踐》在講解編譯原理的各個部分的同時,也在逐步實踐一個現代的編譯器TinyC.等你把整本書看完,差不多自己也可以寫一個TinyC了。作者還對Lex和Yacc這兩個常用的編譯相關的工具進行了很詳細的說明,這一點也是很難在國內的教材中看到的。 推薦了這三本教材,都有英文版和中文版的。很多英文好的同學只喜歡看原版的書,不我的感覺是這三本書的翻譯都很不錯,沒有必要特別去買英文版的。理解理論的實質比理解表面的文字更為重要。 編譯原理的實質 幾乎每本編譯原理的教材都是分成詞法分析,語法分析(LL演算法,遞歸下降演算法,LR演算法),語義分析,運行時環境,中間悶悉代碼,代碼生成,代碼優化這些部分。其實現在很多編譯原理的教材都是按照85,86出版的那本龍書來安排教學內容的,所以那本龍書的內容格式幾乎成了現在編譯原理教材的定式,包括國內的教材也是如此。一般來說,大學裡面的本科教學是不可能把上面的所有部分都認真講完的,而是比較偏重於前面幾個部分。像代碼優化那部分東西,就像個無底洞一樣,如果要認真講,就是單獨開一個學期的課也不可能講得清楚。所以,一般對於本科生,對詞法分析和語法分析掌握要求就相對要高一點了。 詞法分析相對來說比較簡單。可能是詞法分析程序本身實現起來很簡單吧,很多沒有學過編譯原理的人也同樣可以寫出各種各樣的詞法分析程序。不過編譯原理在講解詞法分析的時候,重點把正則表達式和自動機原理加了進來,然後以一種十分標準的方式來講解詞法分析程序的產生。這樣的做法道理很明顯,就是要讓詞法分析從程序上升到理論的地步。 語法分析部分就比較麻煩一點了。現在一般有兩種語法分析演算法,LL自頂向下演算法和LR自底向上演算法。LL演算法還好說,到了LR演算法的時候,困難就來了。很多自學編譯原理的都是遇到LR演算法的理解成問題後就放棄了自學。其實這些東西都是只要大家理解就可以了,又不是像詞法分析那樣非得自己寫出來才算真正的會。像LR演算法的語法分析器,一般都是用工具Yacc來生成,實踐中完全沒有比較自己來實現。對於LL演算法中特殊的遞歸下降演算法,因為其實踐十分簡單,那麼就應該要求每個學生都能自己寫。當然,現在也有不少好的LL演算法的語法分析器,不過要是換在非C平台,比如Java,Delphi,你不能運用YACC工具了,那麼你就只有自己來寫語法分析器。 等學到詞法分析和語法分析時候,你可能會出現這樣的疑問:詞法分析和語法分析到底有什麼?就從編譯器的角度來講,編譯器需要把程序員寫的源程序轉換成一種方便處理的數據結構(抽象語法樹或語法樹),那麼這個轉換的過程就是通過詞法分析和語法分析的。其實詞法分析並非一開始就被列入編譯器的必備部分,只是我們為了簡化語法分析的過程,就把詞法分析這種繁瑣的工作單獨提取出來,就成了現在的詞法分析部分。除了編譯器部分,在其它地方,詞法分析和語法分析也是有用的。比如我們在DOS,Unix,Linux下輸入命令的時候,程序如何分析你輸入的命令形式,這也是簡單的應用。總之,這兩部分的工作就是把不規則的文本信息轉換成一種比較好分析好處理的數據結構。那麼為什麼編譯原理的教程都最終把要分析的源分析轉換成樹這種數據結構呢?數據結構中有Stack,Line,List這么多數據結構,各自都有各自的特點。但是Tree這種結構有很強的遞歸性,也就是說我們可以把Tree的任何結點Node提取出來後,它依舊是一顆完整的Tree。這一點符合我們現在編譯原理分析的形式語言,比如我們在函數裡面使用函樹,循環中使用循環,條件中使用條件等等,那麼就可以很直觀地表示在Tree這種數據結構上。同樣,我們在執行形式語言的程序的時候也是如此的遞歸性。在編譯原理後面的代碼生成的部分,就會介紹一種堆棧式的中間代碼,我們可以根據分析出來的抽象語法樹,很容易,很機械地運用遞歸遍歷抽象語法樹就可以生成這種指令代碼。而這種代碼其實也被廣泛運用在其它的解釋型語言中。像現在流行的Java,.NET,其底層的位元組碼bytecode,可以說就是這中基於堆棧的指令代碼的。 關於語義分析,語法制導翻譯,類型檢查等等部分,其實都是一種完善前面得到的抽象語法樹的過程。比如說,我們寫C語言程序的時候,都知道,如果把一個浮點數直接賦值給一個整數,就會出現類型不匹配,那麼C語言的編譯器是怎麼知道的呢?就是通過這一步的類型檢查。像C++語言這中支持多態函數的語言,這部分要處理的問題就更多更復雜了。大部編譯原理的教材在這部分都是講解一些比較好的處理策略而已。因為新的問題總是在發生,舊的辦法不見得足夠解決。 本來說,作為一個編譯器,起作用的部分就是用戶輸入的源程序到最終的代碼生成。但是在講解最終代碼生成的時候,又不得不講解機器運行環境等內容。因為如果你不知道機器是怎麼執行最終代碼的,那麼你當然無法知道如何生成合適的最終代碼。這部分內容我自我感覺其意義甚至超過了編譯原理本身。因為它會把一個計算機的程序的運行過程都通通排在你面前,你將來可能不會從事編譯器的開發工作,但是只要是和計算機軟體開發相關的領域,都會涉及到程序的執行過程。運行時環境的講解會讓你更清楚一個計算機程序是怎麼存儲,怎麼裝載,怎麼執行的。關於部分的內容,我強烈建議大家看看龍書上的講解,作者從最基本的存儲組織,存儲分配策略,非局部名字的訪問,參數傳遞,符號表到動態存儲分配(malloc,new)都作了十分詳細的說明。這些東西都是我們編寫平常程序的時候經常要做的事情,但是我們卻少去探求其內部是如何完成。 關於中間代碼生成,代碼生成,代碼優化部分的內容就實在不好說了。國內很多教材到了這部分都會很簡單地走馬觀花講過去,學生聽了也只是作為了解,不知道如何運用。不過這部分內容的東西如果要認真講,單獨開一學期的課程都講不完。在《編譯原理及實踐》的書上,對於這部分的講解就恰到好處。作者主要講解的還是一種以堆棧為基礎的指令代碼,十分通俗易懂,讓人看了後,很容易模仿,自己下來後就可以寫自己的代碼生成。當然,對於其它代碼生成技術,代碼優化技術的講解就十分簡單了。如果要仔細研究代碼生成技術,其實另外還有本叫做《》,那本書現在由機械工業出版社引進的,十分厚重,而且是英文原版。不過這本書我沒有把它列為推薦書給大家,畢竟能把龍書的內容搞清楚,在中國已經就算很不錯的高手了,到那個時候再看這本《》也不遲。代碼優化部分在大學本科教學中還是一個不太重要的部分,就是算是實踐過程中,相信大家也不太運用得到。畢竟,自己做的編譯器能正確生成執行代碼已經很不錯了,還談什麼優化呢? 編譯原理的課程畢竟還只是講解原理的課程,不是專門的編譯技術課程。這兩門課程是有很大的區別的。編譯技術更關注實際的編寫編譯器過程中運用到的技術,而原理的課
C. linux編譯器(如gcc)與windows編譯器(vc6.0)有什麼區別求詳細的解答,和例證!
你好!編譯器(在windows下,javac.exe)將源代碼(java文件)編譯為位元組碼(bytecode),存放在class文件中。
位元組碼不能直接在機器上執行,而是通過虛擬機(windows下是java.exe)執行。具體的執行方式有兩種:
1. 一般情況下解釋執行。解釋執行並不是「解釋為用c++語言寫成的程序」,而是jvm把位元組碼看成腳本,根據位元組碼中的指令,由JVM去調用實際的本地方法。
2. 在打開了JIT參數的前提下,jvm會把執行過程中發現的熱點位置,由jvm內部的即時編譯器編譯為本地機器碼直接執行。
編譯器將java文件編譯為class文件,解釋器將class文件變為機器語言
D. 新手如何學習Linux
新手學習建議找准學習方向報班學習。
Linux主體分為「運維」與「開發」兩個方向,無論你是Linux相關從業者,還是說愛好都可以歸類到這里,其中「運維」一般是初學者或者轉行人員的首選,而Linux運維主要是對伺服器穩定、性能與安全方面的維護和調試。
實際上Linux入門並不困難,只要具備Linux基礎,讀懂Linux的命令格式,大多數的服務架構都是可以按照文檔部署出來。當然做Linux開發,個人建議去參加培訓學習更有效率,如果報班學習則大概需要4-6個月時間。
學習主要內容有:
1)網路基礎與linux系統的管理
2)優化及高可用技能
3)虛擬化與雲平台技術
4)開發運維
畢業後可從事的工作有:
1)Linux運維工程師
2)資料庫工程師
3)雲計算運維工程師
4)自動化運維工程師
5)雲計算架構工程師等
互聯網行業目前還是最熱門的行業之一,學習IT技能之後足夠優秀是有機會進入騰訊、阿里、網易等互聯網大廠高薪就業的,發展前景非常好,普通人也可以學習。
想要系統學習,你可以考察對比一下開設有相關專業的熱門學校,好的學校擁有根據當下企業需求自主研發課程的能力,能夠在校期間取得大專或本科學歷,中博軟體學院、南京課工場、南京北大青鳥等開設相關專業的學校都是不錯的,建議實地考察對比一下。
祝你學有所成,望採納。
E. 請問linux下,gcc編譯程序的過程(從讀取源文件到製作可執行程序中間所有過程,越詳細越好)
gcc -S *.c 預處理+反匯編
F. 編譯原理
C語言編譯過程詳解
C語言的編譯鏈接過程是要把我們編寫的一個C程序(源代碼)轉換成可以在硬體上運行的程序(可執行代碼),需要進行編譯和鏈接。編譯就是把文本形式源代碼翻譯為機器語言形式的目標文件的過程。鏈接是把目標文件、操作系統的啟動代碼和用到的庫文件進行組織形成最終生成可執行代碼的過程。過程圖解如下:
從圖上可以看到,整個代碼的編譯過程分為編譯和鏈接兩個過程,編譯對應圖中的大括弧括起的部分,其餘則為鏈接過程。
一、編譯過程
編譯過程又可以分成兩個階段:編譯和匯編。
1、編譯
編譯是讀取源程序(字元流),對之進行詞法和語法的分析,將高級語言指令轉換為功能等效的匯編代碼,源文件的編譯過程包含兩個主要階段:
第一個階段是預處理階段,在正式的編譯階段之前進行。預處理階段將根據已放置在文件中的預處理指令來修改源文件的內容。如#include指令就是一個預處理指令,它把頭文件的內容添加到.cpp文件中。這個在編譯之前修改源文件的方式提供了很大的靈活性,以適應不同的計算機和操作系統環境的限制。一個環境需要的代碼跟另一個環境所需的代碼可能有所不同,因為可用的硬體或操作系統是不同的。在許多情況下,可以把用於不同環境的代碼放在同一個文件中,再在預處理階段修改代碼,使之適應當前的環境。
主要是以下幾方面的處理:
(1)宏定義指令,如 #define a b。
對於這種偽指令,預編譯所要做的是將程序中的所有a用b替換,但作為字元串常量的 a則不被替換。還有 #undef,則將取消對某個宏的定義,使以後該串的出現不再被替換。
(2)條件編譯指令,如#ifdef,#ifndef,#else,#elif,#endif等。
這些偽指令的引入使得程序員可以通過定義不同的宏來決定編譯程序對哪些代碼進行處理。預編譯程序將根據有關的文件,將那些不必要的代碼過濾掉
(3) 頭文件包含指令,如#include "FileName"或者#include <FileName>等。
在頭文件中一般用偽指令#define定義了大量的宏(最常見的是字元常量),同時包含有各種外部符號的聲明。採用頭文件的目的主要是為了使某些定義可以供多個不同的C源程序使用。因為在需要用到這些定義的C源程序中,只需加上一條#include語句即可,而不必再在此文件中將這些定義重復一遍。預編譯程序將把頭文件中的定義統統都加入到它所產生的輸出文件中,以供編譯程序對之進行處理。包含到C源程序中的頭文件可以是系統提供的,這些頭文件一般被放在/usr/include目錄下。在程序中#include它們要使用尖括弧(<>)。另外開發人員也可以定義自己的頭文件,這些文件一般與C源程序放在同一目錄下,此時在#include中要用雙引號("")。
(4)特殊符號,預編譯程序可以識別一些特殊的符號。
例如在源程序中出現的LINE標識將被解釋為當前行號(十進制數),FILE則被解釋為當前被編譯的C源程序的名稱。預編譯程序對於在源程序中出現的這些串將用合適的值進行替換。
預編譯程序所完成的基本上是對源程序的「替代」工作。經過此種替代,生成一個沒有宏定義、沒有條件編譯指令、沒有特殊符號的輸出文件。這個文件的含義同沒有經過預處理的源文件是相同的,但內容有所不同。下一步,此輸出文件將作為編譯程序的輸出而被翻譯成為機器指令。
第二個階段編譯、優化階段。經過預編譯得到的輸出文件中,只有常量;如數字、字元串、變數的定義,以及C語言的關鍵字,如main,if,else,for,while,{,}, +,-,*,\等等。
編譯程序所要作得工作就是通過詞法分析和語法分析,在確認所有的指令都符合語法規則之後,將其翻譯成等價的中間代碼表示或匯編代碼。
優化處理是編譯系統中一項比較艱深的技術。它涉及到的問題不僅同編譯技術本身有關,而且同機器的硬體環境也有很大的關系。優化一部分是對中間代碼的優化。這種優化不依賴於具體的計算機。另一種優化則主要針對目標代碼的生成而進行的。
對於前一種優化,主要的工作是刪除公共表達式、循環優化(代碼外提、強度削弱、變換循環控制條件、已知量的合並等)、復寫傳播,以及無用賦值的刪除,等等。
後一種類型的優化同機器的硬體結構密切相關,最主要的是考慮是如何充分利用機器的各個硬體寄存器存放的有關變數的值,以減少對於內存的訪問次數。另外,如何根據機器硬體執行指令的特點(如流水線、RISC、CISC、VLIW等)而對指令進行一些調整使目標代碼比較短,執行的效率比較高,也是一個重要的研究課題。
2、匯編
匯編實際上指把匯編語言代碼翻譯成目標機器指令的過程。對於被翻譯系統處理的每一個C語言源程序,都將最終經過這一處理而得到相應的目標文件。目標文件中所存放的也就是與源程序等效的目標的機器語言代碼。目標文件由段組成。通常一個目標文件中至少有兩個段:
代碼段:該段中所包含的主要是程序的指令。該段一般是可讀和可執行的,但一般卻不可寫。
數據段:主要存放程序中要用到的各種全局變數或靜態的數據。一般數據段都是可讀,可寫,可執行的。
UNIX環境下主要有三種類型的目標文件:
(1)可重定位文件
其中包含有適合於其它目標文件鏈接來創建一個可執行的或者共享的目標文件的代碼和數據。
(2)共享的目標文件
這種文件存放了適合於在兩種上下文里鏈接的代碼和數據。
第一種是鏈接程序可把它與其它可重定位文件及共享的目標文件一起處理來創建另一個 目標文件;
第二種是動態鏈接程序將它與另一個可執行文件及其它的共享目標文件結合到一起,創建一個進程映象。
(3)可執行文件
它包含了一個可以被操作系統創建一個進程來執行之的文件。匯編程序生成的實際上是第一種類型的目標文件。對於後兩種還需要其他的一些處理方能得到,這個就是鏈接程序的工作了。
二、鏈接過程
由匯編程序生成的目標文件並不能立即就被執行,其中可能還有許多沒有解決的問題。
例如,某個源文件中的函數可能引用了另一個源文件中定義的某個符號(如變數或者函數調用等);在程序中可能調用了某個庫文件中的函數,等等。所有的這些問題,都需要經鏈接程序的處理方能得以解決。
鏈接程序的主要工作就是將有關的目標文件彼此相連接,也即將在一個文件中引用的符號同該符號在另外一個文件中的定義連接起來,使得所有的這些目標文件成為一個能夠被操作系統裝入執行的統一整體。
根據開發人員指定的同庫函數的鏈接方式的不同,鏈接處理可分為兩種:
(1)靜態鏈接
在這種鏈接方式下,函數的代碼將從其所在地靜態鏈接庫中被拷貝到最終的可執行程序中。這樣該程序在被執行時這些代碼將被裝入到該進程的虛擬地址空間中。靜態鏈接庫實際上是一個目標文件的集合,其中的每個文件含有庫中的一個或者一組相關函數的代碼。
(2) 動態鏈接
在此種方式下,函數的代碼被放到稱作是動態鏈接庫或共享對象的某個目標文件中。鏈接程序此時所作的只是在最終的可執行程序中記錄下共享對象的名字以及其它少量的登記信息。在此可執行文件被執行時,動態鏈接庫的全部內容將被映射到運行時相應進程的虛地址空間。動態鏈接程序將根據可執行程序中記錄的信息找到相應的函數代碼。
對於可執行文件中的函數調用,可分別採用動態鏈接或靜態鏈接的方法。使用動態鏈接能夠使最終的可執行文件比較短小,並且當共享對象被多個進程使用時能節約一些內存,因為在內存中只需要保存一份此共享對象的代碼。但並不是使用動態鏈接就一定比使用靜態鏈接要優越。在某些情況下動態鏈接可能帶來一些性能上損害。
我們在linux使用的gcc編譯器便是把以上的幾個過程進行捆綁,使用戶只使用一次命令就把編譯工作完成,這的確方便了編譯工作,但對於初學者了解編譯過程就很不利了,下圖便是gcc代理的編譯過程:
從上圖可以看到:
預編譯
將.c 文件轉化成 .i文件
使用的gcc命令是:gcc –E
對應於預處理命令cpp
編譯
將.c/.h文件轉換成.s文件
使用的gcc命令是:gcc –S
對應於編譯命令 cc –S
匯編
將.s 文件轉化成 .o文件
使用的gcc 命令是:gcc –c
對應於匯編命令是 as
鏈接
將.o文件轉化成可執行程序
使用的gcc 命令是: gcc
對應於鏈接命令是 ld
總結起來編譯過程就上面的四個過程:預編譯、編譯、匯編、鏈接。了解這四個過程中所做的工作,對我們理解頭文件、庫等的工作過程是有幫助的,而且清楚的了解編譯鏈接過程還對我們在編程時定位錯誤,以及編程時盡量調動編譯器的檢測錯誤會有很大的幫助的。
G. 編譯原理的數據結構
編譯原理一直是計算機學習的必修課.
當然,由編譯器的階段使用的演算法與支持這些階段的數據結構之間的交互是非常強大的。編譯器的編寫者盡可能有效實施這些方法且不引起復雜性。理想的情況是:與程序大小成線性比例的時間內編譯器,換言之就是,在0 ( n )時間內,n是程序大小的度量(通常是字元數)。本節將講述一些主要的數據結構,它們是其操作部分階段所需要的,並用來在階段中交流信息。 臨時文件(temporary file):計算機過去一直未能在編譯器時將整個程序保留在存儲器中。這一問題已經通過使用臨時文件來保存翻譯時中間步驟的結果或通過「匆忙地」編譯(也就是只保留源程序早期部分的足夠信息用以處理翻譯)解決了。存儲器的限制現在也只是一個小問題了,現在可以將整個編譯單元放在存儲器之中,特別是在可以分別編譯的語言中時。但是偶爾還是會發現需要在某些運行步驟中生成中間文件。其中典型的是代碼生成時需要反填(backpatch)地址。例如,當翻譯如下的條件語句時 if x = 0 then ... else ... 在知道else部分代碼的位置之前必須由文本跳到else部分:
CMP X,0 JNE NEXT ;;
location of NEXT not yet known < code for then-part > NEXT : < code for else-part >
通常,必須為NEXT的值留出一個空格,一旦知道該值後就會將該空格填上,利用臨時文件可以很容易地做到這一點。
如果想利用上面的編譯原理開發一套屬於自己的編程語言,或者想在一個產品中嵌入編程語言,可以參考zengl開源網開發的zengl編程語言,該編程語言為國人使用C語言開發,裡麵包含兩個部分,一個是編譯器,一個是解釋執行中間代碼的虛擬機。編譯器包含了詞法掃描,語法分析,中間代碼輸出等,虛擬機則類似JAVA一樣解釋執行中間代碼。作者將所有的版本都公布出來,好讓讀者可以由淺入深的做研究,並且為了證明該編程語言的實用性,還結合SDL游戲開發庫開發了一款圖形界面和命令行界面的21點撲克小游戲 。
zengl編程語言目前適用平台為windows和linux (最開始在Linux下使用gcc開發,後來移植到windows平台)
H. 用linux系統是做什麼用的
Linux可以運行在伺服器和其他大型平台之上,如大兆團型機和超級計算機,是一個領先的操作系統。世界上500個最快的超級計算機90%以上運行Linux發行版或變種,最快的前10名超級計算機運行的都是Linux操作系統。
Linux也廣泛應用在嵌入式設備上,如手機、平板電腦、路由器、電視和電子游戲機等。在移動設備上廣泛使用的Android操作系統就是創建在Linux內核之上。
Linux是一款免費的操作系統,用戶可以通過網路或其他途徑免費獲得,並族塌橘可以任意修改其源代碼。來自全世界的無數程序員參與了Linux的修改、編寫工作,程序員可以根據自己的興趣和靈感對其進行改變,這讓Linux吸收了無數程序員的精華,不斷壯大。
(8)linux編譯原理擴展閱讀:
Linux系統的優勢:
1、跨衫寬平台的硬體支持
由於Linux 的內核大部分是用C語言編寫的,並採用了可移植的Unix標准應用程序介面,所以它支持如i386、Alpha、AMD和Sparc等系統平台,以及從個人電腦到大型主機,甚至包括嵌入式系統在內的各種硬體設備。
2、豐富的軟體支持
與其他的操作系統不同的是,安裝了Linux系統後,用戶常用的一些辦公軟體、圖形處理工具、多媒體播放軟體和網路工具等都已無需安裝。
而對於程序開發人員來說,Linux更是一個很好的操作平台,在Linux 的軟體包中,包含了多種程序語言與開發工具,如gcc、cc、C++、Tcl/Tk、Perl、Fortran77 等。
3、完善的網路功能
Linux 內置了很豐富的免費網路伺服器軟體、資料庫和網頁的開發工具,如Apache、Sendmail、VSFtp、SSH、MySQL、php和JSP 等。近年來,越來越多的企業看到了Linux 的這些強大的功能,利用Linux 擔任全方位的網路伺服器。
I. 如何學習linux經驗分享及linux起源與發展
你應該為自己創造一個學習linux的環境--在電腦上裝一個linux或unix
如何選擇版本:北美用redhat,歐洲用SuSE,桌面mandrake較多,而debian是技術最先進的linux開發人員中用debian的最多,其次是redhat,從全球linux各應用領域市場份額來看無疑redhat是最多的,此外還有很多出名的發行版本,不再列舉。
對於初學linux的人來說,我建議是使用redhat,原因如下:
1)現在很多書都是以redhat為例講的,為了與書本協調一致
2)周圍的人都用redhat,交流比較方便
3)redhat應用范圍廣,有典型性和代表性
4)它易於使用和安裝,我們沒有必要把時間浪費在「裝系統」上而應集中精力學習最有用的東西。
【注】現在覺得RH很死板,AS,ES等用在伺服器上或許不錯,Personal desktop用mandrake,debian,suse都不錯,筆者現在用Mandrake,因為她長得漂亮:)
如果你並不打算深入學習linux,而是有諸如適應北京市政府辦公平台遷移到linux上這種需要,那麼中軟,紅旗等中文linux是不錯的選擇
我強烈建議:自己親自動手把linux裝到你的硬碟上,你必須學會獨立安裝linux系統的技能,對於現在的版本來說,其實跟裝WinXP一樣簡單
從此現在開始,請不要以windows的工作方式來考慮問題,應該嘗試挖掘linux身上的「天才unix」的氣質。
三.進階
掌握至少50個以上的常用命令
理解shell管道"|",文件流重定向">"及追加">>"等
熟悉Gnome/KDE等X-windows桌面環境操作
掌握.tgz.rpm.biz等軟體包的常用安裝方法
學習添加外設,安裝設備驅動程序(比如modem)
熟悉Grub/Lilo引導器及簡單的修復操作
熟悉系統固有目錄的名稱及公用
學會用mount命令訪問其他文件系統
了解vi,gcc,gdb等常用編輯器,編譯器,調試器
學習linux環境下的簡單組網
建議:買一本不需要太厚的linux教材,大致可以滿足要求(現在的書越來越多了,還帶很多圖,我當時可沒這么多書)
四.高級應用
澄清一些概念:linux的普通操作與真正的系統管理不能相提並論,後者需要很多知識
1.英語
即使你不學linux,我也強烈建議你學好英文[U.S.english]。因為實質上計算機語言就是英文和字元,所謂的多國語言只是外部包裝。你必須能無障礙的閱讀大量的英文技術文檔在搜索引擎找到的英文網站和網頁中熟練的檢索最好能有用英文直接交流的能力,擺脫了這個障礙,你的學習和理解速度就能快很多,你就有機會拉開和別人的差距。
2.shell[sed/awk]
shell是命令解釋器,是內核與用戶界面交流通道,shell寫的小腳本有點類似於win下的.bat但shell比.bat強大的多,shell不只是解釋命令,更是一種編程語言,有時候幾百行的c用shell幾十行就能代替完成工作,因為shell的工作方式建立在系統已有的眾多應用程序之上
這也是CS中的一個重要思想。此外,shell可以實現工作自動化,這個概念也比較重要sed,awk用來處理文本,歷來很常用。
3.Perl/PHP
漂亮的腳本, CGI的首選,比ASP好,應用面很廣
4.C\C++
C、C++是linux/unix的核心語言,系統代碼都是C寫的
5.ASM
系統底層及內核,硬體,設備驅動程序,嵌入式開發都需要。//走核心路線的話,c\c++,asm最重要
6.Java,Python,Tcl,XML
五、系統管理篇
在熟悉linux的基礎上還需要掌握至少一種unix。我首推Solaris,其次是FreeBSD比如運營級系統一般是Solaris+Oracle/DB2之類的學習apache、ssh、sendmail/Qmail、proftp/vsftp、Samba、Squid、MySQL/PostgreSQL/Oracle、Bind等各種應用伺服器的構架及電子商務的應用熟悉TCP/IP協議族,學習諸如apache+php+proftp+mysql+quota的實現以及大型區域網,分布式集群等各種企業級應用解決方案熟悉多用戶管理,資料庫管理,文件系統,邏輯存儲管理,日誌分析,備份與災難數據修復系統補丁,內核升級,以及在此基礎上的防火牆構架等以保障系統安全在內的各種系統管理技能。
我覺得,如果在此基礎上再掌握路由/交換設備便是一個不錯的系統管理員
各種基於linux的解決方案可參考相關書籍和文獻,必要時用google或各大linux站點站內搜索引擎尋找最新文檔,以避免錯誤和漏洞有幾本技術大全和技術內幕我認為都是這方面不錯的書
六、深入學習linux
我個人理解的讀linux內核需要的基礎:在此之前,希望先把應用層的東西學一下,那樣會比較好理解
1.C
如果學過潭浩強的大學教科書(除了編幾個數學模型好像什麼也做不了的那種),建議再看一下《The C Programming Language》Second Edition這本聖經(如果想學緩沖區溢出,這點C的功力可能是不夠的,還有<C陷阱與缺陷>,<C專家編程>,<C\C++深層探索>,反正經典書看多了是沒有壞處的)
2.asm (AT&T語法,保護模式)
保護模式下的比較復雜,基本上每本講內核的書都會有介紹有80x86 Intel語法的基礎就行,
有興趣可以看看Intel的官方網站
3.數據結構(離散數學)
計算機專業的核心課程,重要性我就不說了
4.操作系統原理
看懂這個再去讀linux吧
5.微機原理/組成原理(數字電路)
底層直接和硬體打交道,所以這個也要
6.了解linux/unix
我想至少你要會操作吧,了解unix的API
7.軟體工程/編譯原理
這方面的經典書去www.china-pub.com可以搜到很多我覺得APUE這種書不適合初學者,還是先看看UPE
從 Unix 到 Linux 這一段歷史
為什麼大家常常會說, Linux 是很穩定的一套操作系統呢?這是因為, Linux 他有個老前輩,那就是 Unix 家族啰!有這個前輩的提攜,讓 Linux 這個小老弟很快的就成為一套穩定而優良的操作系統啦!所以,底下我們來談一談 Unix 到 Linux 的這一段歷史吧!
早在 Linux 出現之前的二十年 ( 大約在 1970 年代 ), 就有一個相當穩定而成熟的操作系統存在了!那就是 Linux 的老大哥『 Unix 』是也!怎麼這么說呢?!他們這兩個傢伙有什麼關系呀?這里就給他說一說啰!眾所皆知的, Linux 的核心是由 Linus Torvalds 在 1991 年的時候給他開發出來的,並且丟到網路上提供大家下載,後來大家覺得這個小東西 ( Linux Kernel ) 相當的小而精巧,所以慢慢的就有相當多的朋友投入這個小東西的研究領域裡面去了!但是為什麼這的小東西這么棒呢?!然而又為什麼大家都可以免費的下載這個東西呢?!嗯!等鳥哥慢慢的唬xx....喔不!聽我慢慢的道來!
一個沒有完成的夢想: Bell, MIT 與 GE 的『 Multics 』系統
早期的計算機並不像現在的個人計算機一般,他可不是一般人碰的到的玩意兒,除非是軍事或者是高科技用途才有可能接觸到這類的 Computer !而如前面所言,有計算機硬體還需要操作系統的配合才能夠發揮計算機的效能,不過,在那個年代,由於計算機算是『奢侈品』,喔~應該說是『貴重物品』,所以,可能一間學校就只有一部大型主機當然,那個年代所謂的大型主機仍然無法提供適度的運算能力的。不過,既然只有一部大型主機,然而有許許多多的教師、學生要想要來使用,怎麼辦呢?為了解決這個問題,在 1960 年代初期,麻省理工學院 ( MIT ) 發展了所謂的『兼容分時系統 ( Compatible Time-Sharing System, CTSS )』,就字面上的意義來看,他主要讓大型主機可以提供多個終端機聯機進入主機使用主機的資源, ( 附帶一提,當時的終端機 ( Terminal ) 本身並沒有軟體或者可供使用的資源,這些終端機要能使用,一定必需要聯機登入主機之後,才能夠使用主機的資源來工作!) 當時可以讓約 30 位使用者聯機使用主機。而為了讓這個分時系統更加的強大,所以,在 1965 年前後由貝爾研究室 ( Bell )、 麻省理工學院 ( MIT ) 及奇異電器公司 ( GE ) 開始來共同開發一個名為 Multics 的大型計畫,目標是想讓大型主機可以聯機 300 位以上的使用者。不過,在奮鬥了四年之後,該計畫仍然宣告不治...喔!是失敗啦!(註: Multics 有復雜、多數的意思。)
一個小型檔案系統的產生:1969 年 Ken Thompson 的小型 file server system
在復雜的 Multics 系統的計畫失敗後,貝爾研究室當然就退出該計畫。就在這個計畫解散之後,曾經參與 Muitics 的貝爾研究室的成員 Ken Thompson 由於自己工作上的需求,需要一套檔案存取的小型操作系統,便在 1969 年的時候以 DEC 公司 ( Digital Equipment Corporation ) 的計算機 PDP-7 為硬體基準,設計了一個適合自己工作環境的小型檔案系統,其中也含有他自行開發的一些小工具。那個系統就是最早期的 Unix 的源頭!當初 Ken 設計這個檔案系統時,主要是為了自己的存取方便所設計的簡單 OS ,因此將原有的 Multics 系統大幅度的簡化,不過,在當時還並沒有 Unix 這個名詞的出現!
Unix 的正式誕生:1973 年 Ritchie 等人以 C 語言寫出第一個正式 Unix 核心
由於 Thompson 寫的那個操作系統實在太好用了,所以在 Bell 研究室內部廣為流傳,並且數度經過改版。到了 1973 年, Bell 研究室的 Dennis Ritchie 等人為了讓這個系統的執行效能更佳化,所以使用編譯效能更好的 C 語言將原有的 1969 年的那個系統之核心大幅度的改寫過,並且確定該操作系統名稱為 Unix,呵呵!那就是最早的 Unix 操作系統啰!不過,由於這個操作系統是由這一群工程師所開發完成的,而且使用者也大多是這方面的工程師,因此造成了後來 Unix 系統介面較難被一般使用者接受的情況 @_@ (註: 相對於 Multics ,Unix 具有單一的意思!)
重要的 Unix 分支: 1977 年 BSD 的誕生
在 Unix 早期的發展中,有一件相當重要的事情,那就是 BSD 的誕生!由於 C 語言是一種高級語言,他可以被應用在不同的硬體架構上面,而 Unix 本身就是 C 語言寫成的!在 Unix 發表之後, 柏克萊大學 ( Berkeley ) 的教授對於這個操作系統相當的有興趣,在經過取得 Unix 的原始碼,並且幾經修改之後,終於在 1977 年發表了第一代的 Berkeley Software Distribution ( BSD ) 。這個 BSD 是 Unix 的一個分支,他的發展對於 Unix 有相當大的影響,例如後來的 Sun 公司就是使用 BSD 發展的核心進行自己商業的 Unix 版本的發展的!