這篇文章主要介紹“hello程序是如何運(yùn)行的”,在日常操作中,相信很多人在hello程序是如何運(yùn)行的問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”hello程序是如何運(yùn)行的”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!
成都創(chuàng)新互聯(lián)公司IDC提供業(yè)務(wù):綿陽機(jī)房托管,成都服務(wù)器租用,綿陽機(jī)房托管,重慶服務(wù)器租用等四川省內(nèi)主機(jī)托管與主機(jī)租用業(yè)務(wù);數(shù)據(jù)中心含:雙線機(jī)房,BGP機(jī)房,電信機(jī)房,移動機(jī)房,聯(lián)通機(jī)房。
在開始之前,我們先看一個最常見的程序:
#include <stdio.h> int main() { printf("hello,world\n"); return 0; }
本文就從上面這個最簡單的hello程序展開,沿著它的生命周期展開學(xué)習(xí).
上面的hello程序其實就是一個由值 0 和 1 組成的位(即比特)序列,8個位成一組,稱為字節(jié)。我們輸入文本hello.c文件中的字符即用每個字節(jié)來表示(大部分計算機(jī)系統(tǒng)都是用ASCII標(biāo)準(zhǔn)來表示字符,即把字節(jié)轉(zhuǎn)為整數(shù)值)。
總結(jié): 信息=位+上下文
hello程序的誕生使用C語言來編寫的,好處是人可以讀懂,但是為了在系統(tǒng)上運(yùn)行,還是得轉(zhuǎn)化為一系列低級的機(jī)器語言指令。
在Unix系統(tǒng)上,從源文件到目標(biāo)文件的轉(zhuǎn)化得靠編譯器, 下面記錄編譯過程:
hello.c需要經(jīng)過預(yù)處理器讀取系統(tǒng)頭文件內(nèi)容并且插入到程序文本中得到一個新的C程序,一般以.i作為擴(kuò)展名;
然后編譯器將文本文件hello.i 翻譯成匯編語言文本文件hello.s
接下來,就該匯編器登場,將匯編語言翻譯成機(jī)器語言指令,并保存到hello.o文件中,此時它是一個二進(jìn)制文件了
最后鏈接階段,將程序中調(diào)用的c標(biāo)準(zhǔn)庫的函數(shù)合并到我們的hello.o程序中,結(jié)果就是一個可執(zhí)行文件,可以被加載到內(nèi)存中,由系統(tǒng)執(zhí)行。
要真正了解程序時如何運(yùn)行的,首先要對系統(tǒng)的硬件組成有一個了解:
總線:貫穿整個系統(tǒng)的電子管道,可以理解為所有的數(shù)據(jù)設(shè)備以及系統(tǒng)之間的數(shù)據(jù)流轉(zhuǎn)都要接到總線上。
I/O設(shè)備:系統(tǒng)與外部世界的聯(lián)系通道;比如鍵盤、鼠標(biāo)、磁盤、顯示器等;
所有的I/O設(shè)置都要通過一個控制器或者適配器與I/O總線相連;
主存:也就是我們常說的內(nèi)存,這是一個臨時存儲設(shè)備,在處理器執(zhí)行程序時,用來存放程序和處理的數(shù)據(jù);
處理器:也就是我們常說的CPU,是解釋存儲在主存中指令的引擎;其核心是一個大小為一個字(定長的字節(jié),根據(jù)系統(tǒng)不同確定)的寄存器,稱為程序計數(shù)器(PC)。在程序運(yùn)行的過程中,PC都是指向主存中的一條機(jī)器語言指令。
從系統(tǒng)通電開始,直到系統(tǒng)斷電,處理器一直在不斷的執(zhí)行PC指向的指令,在更新PC,使其指向下一條指令;
下面列舉幾個CPU在指令要求下可能執(zhí)行的操作:
處理器看上去是它的指令集架構(gòu)的簡單實現(xiàn),但是現(xiàn)代處理器采用非常復(fù)雜的機(jī)制來加速程序的運(yùn)行。因此我們在理解的時候要將處理器的指令集架構(gòu)和處理器的 微體系結(jié)構(gòu)分來:指令集架構(gòu)描述的是每條機(jī)器代碼指令的效果;微體系結(jié)構(gòu)描述的是處理器的實現(xiàn);
加載:從主存復(fù)制一個字到寄存器,已覆蓋原有寄存器的內(nèi)容;
存儲:從寄存器復(fù)制一個字到主存的某個位置,以覆蓋這個位置的原有值;
操作:把兩個寄存器的內(nèi)容復(fù)制到ALU(算數(shù)/邏輯單元),ALU對這兩個字做算數(shù)運(yùn)算,并將結(jié)果存放到一個寄存器中覆蓋原有的內(nèi)容;
跳轉(zhuǎn):從指令本身抽取一個字,并將這個字復(fù)制到PC中,以覆蓋PC中原來的值;
當(dāng)我們在執(zhí)行 ./hello
后,其實發(fā)生的過程是:
剛開始,shell程序執(zhí)行它的指令,等待我們輸入一個命令,當(dāng)我們輸入./hello
后,shell程序?qū)⒆址x入寄存器,在把它存放到內(nèi)存中;
當(dāng)你在敲回車時,shell程序就知道我們已經(jīng)結(jié)束了命令的輸入,然后shell執(zhí)行一系列指令來加載可執(zhí)行文件,將目前文件的代碼和數(shù)據(jù)復(fù)制到主存。注:利用直接存儲器(DMA)技術(shù),數(shù)據(jù)可以不到處理器直接從磁盤到主存。
一旦加載到內(nèi)存中,處理器就開始執(zhí)行程序的main機(jī)器指令,這些指令將“hello,world\n” 字符串中字節(jié)從主存復(fù)制到寄存器文件。再從寄存器文件復(fù)制到顯示設(shè)備,最終展示在屏幕上。
從上面的例子,我們可以總結(jié)出,hello程序經(jīng)歷了從開始在磁盤上,加載時被復(fù)制到主存,處理器運(yùn)行時又從主存復(fù)制到處理器,最后又從處理器復(fù)制到顯示器。
這里從我們程序員角度講,這些復(fù)制就是開銷,那么問題來了,如何減小開銷提高處理器效率呢???
從機(jī)械原理角度來看,存儲設(shè)備越大運(yùn)行越慢;處理器讀磁盤比讀內(nèi)存開銷大1000萬倍,而寄存器文件的讀取速度又比內(nèi)存塊幾乎100倍,加快處理器的運(yùn)行速度比加快主存運(yùn)行速度要容器的多。
針對處理器與主存之間的差異,系統(tǒng)設(shè)計采用了更小更快的存儲設(shè)備,稱之為高速緩存,存放處理器近期可能會需要的信息。這個其實和我們平時開發(fā)程序是一樣的,采用多級緩存,存放熱點數(shù)據(jù),提高系統(tǒng)處理能力。 這里的原理是利用程序具有訪問局部區(qū)域里的數(shù)據(jù)和代碼的趨勢,所以高速緩存中存放了可能經(jīng)常訪問的數(shù)據(jù),這樣大部分操作就能在告訴緩存中完成。
請看下面的存儲器層次的結(jié)構(gòu),相信你會一目了然:
如圖所示,上一層存儲器是下一層的高速緩存。
我們寫的程序,沒有直接訪問鍵盤、顯示器、磁盤等硬件,而是依賴操作系統(tǒng)提供的服務(wù),所以可以把操作系統(tǒng)看成是應(yīng)用程序和硬件之間一層軟件。
操作系統(tǒng)有兩大功能:
防止硬件被濫用;
對應(yīng)用程序屏蔽底層復(fù)雜而通常又大不相同的硬件設(shè)備,提供簡單一致的機(jī)制;
操作系統(tǒng)通常抽象出幾個概念:進(jìn)程、虛擬內(nèi)存、文件;
進(jìn)程是操作系統(tǒng)對一個正在運(yùn)行的應(yīng)用程序的抽象,一個系統(tǒng)可以同時運(yùn)行多個進(jìn)程。
單核處理器一個時刻只能執(zhí)行一個程序,而目前的多核處理器能同時執(zhí)行多個程序。無論單核還是多核,一個CPU看上去都是在并發(fā)執(zhí)行多個進(jìn)程,這是通過處理器在進(jìn)程間切換來實現(xiàn)的,這種切換被稱為 上下文切換;
進(jìn)程之間的切換是由操作系統(tǒng)內(nèi)核管理的,內(nèi)核是操作系統(tǒng)常駐主存的部分。當(dāng)應(yīng)用程序需要操作系統(tǒng)的某些操作時,比如讀寫文件,它就執(zhí)行一條系統(tǒng)調(diào)用指令,將控制權(quán)傳遞給內(nèi)核。然后內(nèi)核執(zhí)行被請求的操作并返回應(yīng)用程序。 注意,內(nèi)核不是一個獨(dú)立的進(jìn)程,它是系統(tǒng)管理所有進(jìn)程所用代碼和數(shù)據(jù)結(jié)構(gòu)的集合。
一個進(jìn)程實際上是由多個稱為線程的執(zhí)行單元組成,每個線程都運(yùn)行在進(jìn)程的上下文中,并共享同樣的代碼和全局?jǐn)?shù)據(jù)。
優(yōu)點:比進(jìn)程之間更容易共享數(shù)據(jù);一般來講也比進(jìn)程更高效;
這是一個抽象概念,它為每個進(jìn)程提供了一個假象,即每個進(jìn)程都在單獨(dú)使用主存,每個進(jìn)程看到的內(nèi)存都是一致的,稱為虛擬地址空間,如下圖所示,地址是從小往上增大的:
文件就是字節(jié)序列,所有的I/O設(shè)備,甚至網(wǎng)絡(luò)都可以看成是文件;
多核處理器是將多個CPU集成到一個集成電路芯片上。多核處理器組織架構(gòu)如下:
超線程:稱為同時多線程,允許一個CPU同時執(zhí)行多個并發(fā)流的技術(shù)。Intel Core i7 處理器可以讓每個核執(zhí)行兩個線程。
在處理里,指令集架構(gòu)提供了對實際處理器硬件的抽象,使用這個抽象,機(jī)器代碼表現(xiàn)的好像運(yùn)行在一個一次只執(zhí)行一條指令的處理器上。不管底層多復(fù)雜精細(xì),哪怕可以并發(fā)的執(zhí)行多條指令,擔(dān)又總是與那個簡單有序的模型保持一致。只要模型一樣,不同的處理器實現(xiàn)也能執(zhí)行同樣的機(jī)器代碼,而又提供不同的開銷和性能。這種抽象思想簡直太重要了,在整個計算機(jī)科學(xué)中也隨處可見,比如java類的生命和C語言的函數(shù)原型,以及計算機(jī)網(wǎng)絡(luò)的分層。
看了上面這副圖可以總結(jié)為:
文件是對I/O設(shè)置的抽象;
虛擬內(nèi)存是對主存和磁盤的抽象;
進(jìn)程是對處理器、主存和I/O設(shè)備的抽象;
至此,本章的學(xué)習(xí)就結(jié)束了,主要對計算機(jī)系統(tǒng)的組成和程序運(yùn)行有了大框架的認(rèn)知,后續(xù)繼續(xù)進(jìn)行深入學(xué)習(xí)。
信息=位+上下文,什么是上下文?工作中有哪些例子?
每一段程序都有很多外部變量。只有像Add這種簡單的函數(shù)才是沒有外部變量的。一旦你的一段程序有了外部變量,這段程序就不完整,不能獨(dú)立運(yùn)行。你為了使他們運(yùn)行,就要給所有的外部變量一個一個寫一些值進(jìn)去。這些值的集合就叫上下文。 比如:C++的lambda表達(dá)式里面,[寫在這里的就是上下文](int a, int b){ ... }
RISC指令集和CISC指令集有什么區(qū)別,它們的典型CPU有哪些?
CSIC(Complex Instruction Set Computer) 復(fù)雜指令集的CPU; CISC體系的設(shè)計理念是用最少的指令來完成任務(wù)(譬如計算乘法只需要一條MUL指令即可),因此CISC的CPU本身設(shè)計復(fù)雜、工藝復(fù)雜,但好處是編譯器好設(shè)計。CISC出現(xiàn)較早,至今Intel還一直采用CISC設(shè)計;
RSIC(Reduced Instruction Set Computer) 精簡指令集的CPU; RISC的設(shè)計理念是讓軟件來完成具體的任務(wù),CPU本身僅提供基本功能指令集,即:指令集中指令的數(shù)量相對很少。這種設(shè)計理念相對于CISC的設(shè)計理念,CPU的設(shè)計和工藝簡單了,但是編譯器的設(shè)計變復(fù)雜了
典型CPU: 一般典型CISC的CPU指令數(shù)在300條左右。ARM的CPU(作為典型的RISC的CPU)常用指令數(shù)在30條左右。 一般來說,CISC的CPU的功耗更高,一般用在PC機(jī)和筆記本電腦中。相對來說,RISC的CPU的功耗更低,一般用在嵌入式領(lǐng)域。
基于棧的CPU和基于寄存器的CPU有什么區(qū)別?
這個問題可以將JVM看成是一個基于棧的CPU,它在運(yùn)行程序的時候都是用棧,代碼必須使用這些指令來移動變量(即push和pop);
到此,關(guān)于“hello程序是如何運(yùn)行的”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>
當(dāng)前名稱:hello程序是如何運(yùn)行的
文章分享:http://jinyejixie.com/article24/igodje.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站排名、靜態(tài)網(wǎng)站、服務(wù)器托管、企業(yè)網(wǎng)站制作、手機(jī)網(wǎng)站建設(shè)、微信小程序
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)