偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

程序是怎么一步步運(yùn)行起來(lái)的?

系統(tǒng) 其他OS
當(dāng)操作系統(tǒng)決定把CPU分配給剛創(chuàng)建的程序時(shí)會(huì)用這個(gè)值去初始化CPU的指令寄存器,這樣CPU就知道該從哪里開(kāi)始運(yùn)行該程序了。

大家好,我是小風(fēng)哥,今天聊聊程序是怎么一步步運(yùn)行起來(lái)的。

第一步我們需要知道到底什么是可執(zhí)行程序,所謂可執(zhí)行程序就是一個(gè)保存一系列機(jī)器指令的文件:

圖片圖片

chrome.exe就是上千萬(wàn)上億條指令組成的一個(gè)普通文件,和你寫(xiě)的txt文件沒(méi)有任何本質(zhì)的區(qū)別,只不過(guò)txt文件中的內(nèi)容是給人看的,而可執(zhí)行程序中的內(nèi)容是給CPU執(zhí)行的。

圖片圖片

現(xiàn)在有了可執(zhí)行程序,接著我們來(lái)運(yùn)行它,運(yùn)行一個(gè)程序很簡(jiǎn)單,雙擊圖標(biāo)或者在命令行中運(yùn)行命令:

圖片圖片

這一步發(fā)生了什么?

我們已經(jīng)知道可執(zhí)行程序其實(shí)就是一個(gè)文件,文件是保存在磁盤(pán)上的。

當(dāng)我們雙擊或者在命令行中運(yùn)行命令后,第一件事就要找到可執(zhí)行文件保存在了磁盤(pán)的哪個(gè)位置:

圖片圖片

誰(shuí)來(lái)完成這件事?答案就是操作系統(tǒng)。

實(shí)際上操作系統(tǒng)也是一個(gè)程序,操作系統(tǒng)是管理我們寫(xiě)的程序的程序。

操作系統(tǒng)在文件系統(tǒng)的幫助下找到可執(zhí)行程序,接下來(lái)操作系統(tǒng)開(kāi)始解析可執(zhí)行程序,實(shí)際上可執(zhí)行程序中并不只包含機(jī)器指令,這里還有很多其它信息,在Linux下可執(zhí)行程序一般遵循ELF文件格式:

圖片圖片

根據(jù)可執(zhí)行程序的格式操作系統(tǒng)就能找到機(jī)器指令或程序運(yùn)行依賴(lài)的全局變量等信息保存在了文件的哪個(gè)位置。

既然操作系統(tǒng)已經(jīng)識(shí)別出了可執(zhí)行程序,接下來(lái)就是重要的一步:加載,load。

所謂加載就是把磁盤(pán)上可執(zhí)行程序中的指令和程序依賴(lài)的全局變量等數(shù)據(jù)copy到內(nèi)存中:

圖片圖片

既然是copy到內(nèi)存,那么顯然操作系統(tǒng)需要為接下來(lái)要運(yùn)行的程序分配內(nèi)存。

操作系統(tǒng)在內(nèi)存中找到一段大小合適的空閑內(nèi)存分配給接下來(lái)要運(yùn)行的程序:

圖片圖片

然后在該內(nèi)存中劃分出幾個(gè)區(qū)域,這幾個(gè)區(qū)域就是我們熟悉的代碼區(qū)、數(shù)據(jù)區(qū)、堆區(qū)和棧區(qū):

圖片圖片


其中代碼區(qū)和數(shù)據(jù)區(qū)中的內(nèi)容來(lái)自可執(zhí)行程序的代碼段和數(shù)據(jù)段:

圖片圖片

而堆區(qū)和棧區(qū)則是程序在運(yùn)行過(guò)程中使用的,這兩個(gè)區(qū)域中的內(nèi)容不依賴(lài)可執(zhí)行程序本身。

值得注意的是,所謂的堆區(qū)和棧區(qū)只是一個(gè)抽象的概念,真正的物理內(nèi)存中并沒(méi)有一塊所謂的堆區(qū)或者棧區(qū)。

任何一段內(nèi)存都可以被用作堆區(qū)或者棧區(qū),這就像停車(chē)場(chǎng)有vip區(qū)或者普通區(qū),所謂vip區(qū)只不過(guò)一種約定,普通區(qū)和vip區(qū)的停車(chē)位沒(méi)有任何本質(zhì)的不同,作為停車(chē)場(chǎng)管理員只要你高興實(shí)際上可以把任何一塊普通區(qū)劃分為vip區(qū)。

當(dāng)然,程序的內(nèi)存區(qū)域中除了看到的這些區(qū)域可能還有其它區(qū)域,這取決于程序是否依賴(lài)動(dòng)態(tài)庫(kù)。

如果該程序依賴(lài)動(dòng)態(tài)庫(kù),那么在程序運(yùn)行時(shí)還需要把依賴(lài)的動(dòng)態(tài)庫(kù)也加載進(jìn)來(lái),加載到哪里呢?

不要忘了堆區(qū)和棧區(qū)的增長(zhǎng)方向是相反的,因此這中間的空閑區(qū)域正好可以利用起來(lái)存放動(dòng)態(tài)庫(kù):

圖片圖片

這一步完成之后程序就算加載完畢接下來(lái)可以運(yùn)行了,但程序是怎么運(yùn)行的呢?CPU怎么能知道該從哪里開(kāi)始運(yùn)行這個(gè)程序呢?

答案還得在可執(zhí)行程序中尋找。

編譯器在編譯生成可執(zhí)行程序時(shí)會(huì)記錄下這個(gè)程序第一條指令的所在位置,以elf可執(zhí)行程序?yàn)槔?,使用readelf工具你可以查看elf可執(zhí)行程序的內(nèi)容:

圖片圖片

注意看Entry point address這一項(xiàng),這就是該程序的第一條機(jī)器指令所在地址。

當(dāng)操作系統(tǒng)決定把CPU分配給剛創(chuàng)建的程序時(shí)會(huì)用這個(gè)值去初始化CPU的指令寄存器,這樣CPU就知道該從哪里開(kāi)始運(yùn)行該程序了。

圖片圖片

就這樣程序開(kāi)始運(yùn)行。

這就是你雙擊一個(gè)圖標(biāo)背后的故事。

責(zé)任編輯:武曉燕 來(lái)源: 碼農(nóng)的荒島求生
相關(guān)推薦

2024-08-06 09:29:54

程序機(jī)器指令字符串

2024-09-12 10:04:06

內(nèi)存程序系統(tǒng)

2024-09-30 09:56:59

2017-01-19 21:08:33

iOS路由構(gòu)建

2018-12-24 10:04:06

Docker存儲(chǔ)驅(qū)動(dòng)

2018-07-13 15:36:52

2019-03-05 14:09:27

Docker存儲(chǔ)容器

2019-07-09 15:23:22

Docker存儲(chǔ)驅(qū)動(dòng)

2016-11-02 18:54:01

javascript

2017-12-25 11:50:57

LinuxArch Linux

2010-03-04 16:28:17

Android核心代碼

2024-11-11 10:28:33

操作系統(tǒng)Unix系統(tǒng)

2025-04-03 01:45:00

2024-06-27 08:30:36

內(nèi)存擴(kuò)容堆區(qū)

2025-03-28 09:39:15

CPU指令信號(hào)

2011-05-10 10:28:55

2019-04-01 10:15:02

2018-06-11 15:30:12

2018-04-23 14:23:12

2020-12-24 11:19:55

JavaMapHashMap
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)