CPU工作原理
????????CPU工作原理是它先從內(nèi)存中獲取并執(zhí)行一條指令祭玉,然后再從內(nèi)存中獲取并執(zhí)行下一條指令,諸如此類(一個吉赫茲的CPU一秒鐘能重復(fù)這樣的操作大約十億次)库物。CPU有自己的小工作區(qū)一由若干個寄存器組成拗秘,每個寄存器都可以儲存一個數(shù)字侨核。一個寄存器儲存下一條指令的內(nèi)存和地址草穆,CPU使用該地址來獲取和更新下一條指令。在獲取指令后搓译,CPU在另用一個寄存器中儲存該指令悲柱,并更新第一個寄存器儲存下一條指令的地址。CPU能理解的指令有限(這些指令的集合叫做指令集)些己。而且這些指令相當(dāng)具體豌鸡,其中的許多指令都是用于請求計算機(jī)把一個數(shù)字從一個位置移動到另一個位置嘿般。例如從內(nèi)存移動到寄存器。
????????儲存在計算機(jī)中的所有內(nèi)容都是數(shù)字涯冠。計算機(jī)以數(shù)字的形式儲存數(shù)字和字符炉奴。每個字符都有一個數(shù)字碼。計算機(jī)載入寄存器的指令也以數(shù)字形式儲存指令集中的每條指令都有一個數(shù)字碼功偿。計算機(jī)程序最終必須以數(shù)字指令碼(即盆佣,機(jī)器語言)來表示往堡。
????????如果希望計算機(jī)做某些事械荷,就必須為其提供特殊的指令集列表(程序),確切的告訴計算機(jī)要做的事以及如何去做虑灰。你必須使用計算機(jī)能明白的語言(機(jī)器語言)去創(chuàng)建程序吨瞎。這是一項(xiàng)繁瑣、乏味穆咐、費(fèi)力的任務(wù)颤诀。計算機(jī)要完成兩數(shù)相加這樣簡單的事,就得分類幾個步驟对湃。
1崖叫,從內(nèi)存位置2000上把一個數(shù)字拷貝到內(nèi)存1。
2拍柒,從內(nèi)存位置2004上把另一個數(shù)字拷貝到寄存器2心傀。
3,把寄存器2中內(nèi)容與寄存器1中內(nèi)容想加拆讯,把結(jié)果放到寄存器1中脂男。
4,把寄存器1中內(nèi)容拷貝到2008种呐。
而你要做的是宰翅,必須用數(shù)字碼來表示以上每個步驟!爽室。
高級計算機(jī)語言和編譯器
????????高級編程語言(如汁讼,C)以多種方式簡化了編程工作。首先阔墩,不必用數(shù)字碼表示指令嘿架;其次,使用的指令更貼近你如何想這個問題戈擒,而不是類似計算機(jī)那樣的繁多工作眶明。使用高級編程語言 可以在更抽象的層面表達(dá)你的想法,不用考慮CPU在完成任務(wù)時具體需要哪些步驟筐高。例如兩數(shù)想加這樣寫tltal = mine + yours;
搜囱。對我們而言丑瞧,光看這條代碼就知道要干什么;而看用機(jī)器語言寫成等價指令(多條已數(shù)字碼表示的指令)則費(fèi)勁得多蜀肘。但是對計算機(jī)而言卻恰恰相反绊汹。在計算機(jī)看來,高級指令就是一堆無法理解的無用數(shù)據(jù)扮宠。編譯器就在這里派上了用場西乖。編譯器就是把高級語言程序翻譯成計算機(jī)能理解的機(jī)器語言指令集的程序。程序員進(jìn)行高級思維活動坛增,而編譯器則負(fù)責(zé)處理亢長乏味的細(xì)節(jié)工作获雕。
????????編譯器還有一個優(yōu)勢。一般而言收捣,不同CPU制造商使用的指令系統(tǒng)和編碼格式不同届案。例如,用Intel Core i7CPU編寫的機(jī)器語言程序?qū)τ贏RM CortexA57 CPU而言什么都不是罢艾。但是可以找到與特定類型CPU匹配的編譯器楣颠。因此適用合適的編譯器或編譯器集,便可讓編譯器集翻譯成不同CPU使用的機(jī)器語言咐蚯。
????????簡而言之童漩,高級語言以更抽象的方式描述行為,不受于特定CPU或指令集春锋。
使用C語言的7個步驟
????????C是編譯型語言矫膨。編寫C程序理想狀態(tài)下是7個步驟如下圖
????????實(shí)際使用過程中 尤其是在比較大型的項(xiàng)目中,可能要做一些重復(fù)工作看疙,根據(jù)下一個步驟的情況來調(diào)整或改進(jìn)上一個步驟豆拨。
?????????????????????????????????編程機(jī)制
????????生成程序的具體過程因計算機(jī)環(huán)境而異。C是可移植性語言能庆,因此可以在許多環(huán)境中使用施禾,包括UNIX、Linux搁胆、MS-DOS弥搞、Windows和Macintosh OS。
????????用C語言編寫程序時渠旁,編寫的內(nèi)容被儲存在文本文件中攀例,該文件被稱為源代碼文件(source code file),大部分C系統(tǒng)顾腊,都要求以.c結(jié)尾(如粤铭,wordcount.c和bugdet.c)在文件名中,點(diǎn)號(.)前面部分被稱為基本名(basename)點(diǎn)號后面稱為擴(kuò)展名(extension)杂靶,基本名與擴(kuò)展名的組合(例 budget.c)就是文件名梆惯。
?????????????目標(biāo)代碼文件酱鸭、可執(zhí)行文件和庫
????????C編程的基本策略是,用程序把源代碼文件轉(zhuǎn)換成可執(zhí)行文件(其中包含可直接運(yùn)行的機(jī)器語言代碼)垛吗。典型的C實(shí)現(xiàn)通過編譯和鏈接兩個步驟來完成這一過程凹髓。編譯器把源代碼轉(zhuǎn)換成中間代碼,鏈接器把中間代碼和其他代碼合并怯屉,生成可執(zhí)行文件蔚舀。C使用這種分而治之的方法方便對程序進(jìn)行模塊化,可以獨(dú)立編譯單獨(dú)的模塊锨络,稍后再用鏈接器合并以編譯的模塊赌躺。通過這種方式,如果只要改某個模塊足删,不必因此編譯其他模塊寿谴。另外锁右,鏈接器還將你編寫的程序和預(yù)編譯的庫代碼合并失受。
????????中間文件有多種形式。最普遍的即把源代碼轉(zhuǎn)換為機(jī)器語言代碼咏瑟,并把結(jié)果放到目標(biāo)代碼文件(簡稱目標(biāo)文件)拂到。雖然目標(biāo)文件中包含機(jī)器語言代碼,但是并不能直接運(yùn)行該文件码泞。因?yàn)槟繕?biāo)文件中儲存的是編譯器翻譯的源代碼兄旬,這不是一個完整的程序。
????????目標(biāo)文件缺失啟動代碼(startup code)啟動代碼充當(dāng)著程序和操作系統(tǒng)之間的接口余寥。例如领铐,可以在MS Windows或Linux系統(tǒng)下運(yùn)行IBM PC兼容機(jī)。這兩種情況下使用硬件相同宋舷,所以目標(biāo)代碼相同绪撵,但是Windows和linux所需的啟動代碼不同,因?yàn)檫@些系統(tǒng)的處理程序方式不同祝蝠。
????????目標(biāo)代碼還缺少函數(shù)庫音诈。幾乎所有的C程序都要使用C標(biāo)準(zhǔn)中的函數(shù)。目標(biāo)代碼并不包含函數(shù)代碼绎狭,函數(shù)真正的代碼儲存在另一個被稱為庫的文件中细溅。庫文件中有許多函數(shù)的目標(biāo)代碼。
????????鏈接器的作用是儡嘶,把你編寫的目標(biāo)代碼喇聊,系統(tǒng)的標(biāo)準(zhǔn)啟動代碼和庫代碼這三部分合并成一個文件,即可執(zhí)行文件蹦狂。對于褲代碼誓篱,鏈接器只會把程序中要用到的庫函數(shù)代碼提取出來邻耕。
????????目標(biāo)文件和可執(zhí)行文件都是由機(jī)器語言指令組成的。然而目標(biāo)文件中只包含編譯器為你編寫的代碼翻譯的機(jī)器語言代碼燕鸽,可執(zhí)行文件中還包含你編寫的程序中使用的庫函數(shù)和啟動代碼的機(jī)器代碼兄世。
????????C編譯器會創(chuàng)建一個與源代碼基本名相同的目標(biāo)代碼文件,但是其擴(kuò)展名是.o啊研。鏈接器一旦生成了完整的可執(zhí)行程序御滩,就會將其刪除。如果原始程序有多個源代碼文件党远,則保留目標(biāo)代碼文件削解。
PC的命令行編譯器
????????C編譯器不是標(biāo)準(zhǔn)Windows軟件包的一部分,因此需要從別處獲取并安裝C編譯器沟娱。例如下載Cygwin和MinGW氛驮,這樣便可以在PC上通過命令行使用GCC編譯器Cywin在自己的視窗運(yùn)行,模仿linux命令行環(huán)境济似,有一行命令提示矫废。MinGW在Windows的命令提示模式中運(yùn)行。與GCC最新版本一樣砰蠢,支持c99和c11蓖扑。Borland的C++編譯器5.5也可以下載,支持c90台舱。
????????源代碼應(yīng)該是文本文件律杠,不是字處理器文件(系處理器文件包含很多額外的信息,如字體和格式等)竞惋。因此要使用文本編輯器(如Winfows Notepad)來編輯代碼柜去。如果是用字處理器,要以文本模式另存文件拆宛。源代碼文件的擴(kuò)展名應(yīng)該是.c嗓奢。一些字處理器會為文本文件自動添加.txt擴(kuò)展名,如果出現(xiàn)則要更改文件名胰挑,把txt改為.c蔓罚。
????????通常C編譯器生成的中間目標(biāo)代碼文件的擴(kuò)展名是.obj(也可能有其他擴(kuò)展名)。與UNIX編譯器不同瞻颂,這些編譯器在完成編譯后通常不會刪除這些中間文件豺谈。有些編譯器生產(chǎn)帶.asm擴(kuò)展名的匯編語言文件,而有些編譯器則使用自己特有的格式贡这。
???????#一些編譯器在編譯后會自動運(yùn)行鏈接器茬末,另一些要求用戶手動運(yùn)行鏈接器。在可執(zhí)行文件中鏈接器的結(jié)果是,在原始的源代碼基本名后面加上.exe的擴(kuò)展名丽惭。例如击奶,編譯和鏈接concrete.c源代碼文件,生成的是concrete.exe文件责掏」窭可以在命令行輸入基本名來運(yùn)行該程序:
C>concrete