国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【Linux初階】進(jìn)程地址空間 | CUP與可執(zhí)行程序的交互原理

這篇具有很好參考價(jià)值的文章主要介紹了【Linux初階】進(jìn)程地址空間 | CUP與可執(zhí)行程序的交互原理。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

???hello,各位讀者大大們你們好呀??

????系列專欄:【Linux初階】

????本篇內(nèi)容:計(jì)算機(jī)空間初識(shí)(子進(jìn)程變量修改實(shí)驗(yàn)),感性理解進(jìn)程虛擬地址空間,進(jìn)程地址空間基礎(chǔ)(概念、區(qū)域劃分與調(diào)整、程序?qū)?nèi)存數(shù)據(jù)的修改、按需分配虛擬地址空間),解答為什么存在虛擬地址空間(防止非法越界、方便解耦、保證進(jìn)程獨(dú)立性、統(tǒng)一編譯方便使用),其中重點(diǎn)講解統(tǒng)一編譯中CPU與可執(zhí)行程序的交互原理

????作者簡(jiǎn)介:本科在讀,計(jì)算機(jī)海洋的新進(jìn)船長(zhǎng)一枚,請(qǐng)多多指教( ????? ) ??-

目錄

一、你真的了解計(jì)算機(jī)數(shù)據(jù)空間分布嗎?

二、感性理解進(jìn)程虛擬地址空間

三、進(jìn)程地址空間基礎(chǔ)

1.相關(guān)的基礎(chǔ)概念

2.區(qū)域劃分與調(diào)整

3.程序是如何更改內(nèi)存中的數(shù)據(jù)的?

4.操作系統(tǒng)會(huì)根據(jù)進(jìn)程的需求分配虛擬地址空間

四、為什么存在地址空間?

1.防止非法越界訪問

2.方便進(jìn)程解耦,保證進(jìn)程獨(dú)立性

3.統(tǒng)一編譯,方便使用

(1)可執(zhí)行文件中有地址嗎?

(2)編譯器的編碼方式

(3)物理地址的來源

(4)CPU與可執(zhí)行程序交互的原理

(5)邏輯地址知識(shí)補(bǔ)充

結(jié)語


一、你真的了解計(jì)算機(jī)數(shù)據(jù)空間分布嗎?

在以前的學(xué)習(xí)中,大家可能很早已經(jīng)見過類似下面這樣的空間分布圖了

【Linux初階】進(jìn)程地址空間 | CUP與可執(zhí)行程序的交互原理

可是我們很多同學(xué)對(duì)它并沒有深入理解,很多同學(xué)認(rèn)為這個(gè)空間實(shí)際上就是我們的內(nèi)存,但是真的是這樣嗎?

我們直接通過一段代碼來驗(yàn)證一下

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int g_val = 0;
int main()
{
	pid_t id = fork();
	if (id < 0) {
		perror("fork");
		return 0;
	}

	else if (id == 0) { //child
		printf("child[%d]: %d : %p\n", getpid(), g_val, &g_val);
	}
	else { //parent
		printf("parent[%d]: %d : %p\n", getpid(), g_val, &g_val);
	}
	sleep(1);
	return 0;
}

輸出

//與環(huán)境相關(guān),觀察現(xiàn)象即可
parent[2995]: 0 : 0x80497d8
child[2996] : 0 : 0x80497d8

我們發(fā)現(xiàn),輸出出來的變量值和地址是一模一樣的,很好理解呀,因?yàn)樽舆M(jìn)程按照父進(jìn)程為模版,父子并沒有對(duì)變量進(jìn)行進(jìn)行任何修改??墒菍⒋a稍加改動(dòng):

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int g_val = 0;

int main()
{
	pid_t id = fork();
	if (id < 0) {
		perror("fork");
		return 0;
	}
	else if (id == 0) { //child,子進(jìn)程肯定先跑完,也就是子進(jìn)程先修改,完成之后,父進(jìn)程再讀取
		g_val = 100;
		printf("child[%d]: %d : %p\n", getpid(), g_val, &g_val);
	}
	else { //parent
		sleep(3);
		printf("parent[%d]: %d : %p\n", getpid(), g_val, &g_val);
	}
	sleep(1);
	return 0;
}

輸出結(jié)果:

//與環(huán)境相關(guān),觀察現(xiàn)象即可
child[3046]: 100 : 0x80497e8
parent[3045] : 0 : 0x80497e8

我們發(fā)現(xiàn),父子進(jìn)程,輸出地址是一致的,但是變量?jī)?nèi)容不一樣!能得出如下結(jié)論:

  • 變量?jī)?nèi)容不一樣,所以父子進(jìn)程輸出的變量絕對(duì)不是同一個(gè)變量。
  • 但地址值是一樣的,說明,該地址絕對(duì)不是物理地址!
  • 曾經(jīng)我們學(xué)習(xí)語言的基本地址(指針),并不是對(duì)應(yīng)的物理地址。
  • 在Linux地址下,這種地址叫做 虛擬地址。
  • 我們?cè)谟肅/C++語言所看到的地址,全部都是虛擬地址!物理地址,用戶一概看不到,由OS統(tǒng)一管理。

注意:OS必須負(fù)責(zé)將 虛擬地址 轉(zhuǎn)化成 物理地址 。


二、感性理解進(jìn)程虛擬地址空間

進(jìn)程會(huì)認(rèn)為自己是獨(dú)占系統(tǒng)資源的(實(shí)際上不是)

這里我舉一個(gè)通俗易懂的例子:

peter是美國一個(gè)擁有十億美元的大富翁,他擁有三個(gè)私生子,且這三個(gè)私生子互不知道其他私生子的存在,三個(gè)兒子分別是工廠老板、證券交易員、學(xué)生。每個(gè)兒子都認(rèn)為自己是peter十億美金的繼承者。

在他們工作的過程中,需要向peter索取金錢(工廠老板為維持家族企業(yè)正常運(yùn)轉(zhuǎn),發(fā)放工人工資,結(jié)清貨款;證券交易員維持正常投資,管理部分家族現(xiàn)金資產(chǎn);學(xué)生為繳納學(xué)費(fèi)等),他們向peter索要的金錢有多有少,但是都不會(huì)提出過分的要求(比如直接索要十億美金),如果他們提出過分要求,會(huì)被peter拒絕。

peter在三個(gè)兒子工作的時(shí)候,會(huì)給兒子們“畫餅”,比如他會(huì)對(duì)第一個(gè)兒子說:你好好干,只要你管理好我們的家族企業(yè),提高我們的工廠效益,以后我的十億美金就都是你的了。

其中大富翁peter就相當(dāng)于我們的操作系統(tǒng),十億美金就相當(dāng)于操作系統(tǒng)管理的內(nèi)存資源。其中兒子就相當(dāng)于我們平時(shí) malloc、new等向系統(tǒng)索要資源的進(jìn)程。兒子們獲取的金錢就相當(dāng)于內(nèi)存或者在語言上稱為對(duì)象空間(內(nèi)存)。peter給三個(gè)兒子畫的“大餅”就相當(dāng)于進(jìn)程地址空間。計(jì)算機(jī)通過軟件,給進(jìn)程“畫餅”。

【Linux初階】進(jìn)程地址空間 | CUP與可執(zhí)行程序的交互原理

?———— 我是一條知識(shí)分割線 ————

那實(shí)際上如何“畫餅”呢?在此之前,我們要知道“餅”是什么,畫餅的本質(zhì):在你大腦中的藍(lán)圖 - 數(shù)據(jù)結(jié)構(gòu)對(duì)象地址空間)。

每個(gè)兒子(進(jìn)程)都可以根據(jù)peter(操作系統(tǒng))為自己畫的“餅”(數(shù)據(jù)結(jié)構(gòu)對(duì)象/地址空間)向peter要錢(內(nèi)存資源)

?【Linux初階】進(jìn)程地址空間 | CUP與可執(zhí)行程序的交互原理

———— 我是一條知識(shí)分割線 ————?

?我們已經(jīng)知道“餅”是什么,那么問題又來了,我們都知道兒子(進(jìn)程)需要被管理,那么peter(操作系統(tǒng))為兒子(進(jìn)程)提供的“餅”(數(shù)據(jù)結(jié)構(gòu)對(duì)象/地址空間)需要被管理嗎?答案是:要的!因?yàn)椴荒軐⒔o大兒子的承諾許錯(cuò)給二兒子或三兒子,所以“餅”也要被管理。

如果進(jìn)程中有500個(gè)進(jìn)程,操作系統(tǒng)需要給每個(gè)進(jìn)程創(chuàng)建地址空間,進(jìn)程會(huì)被PCB管理,地址空間需要怎么管理呢?答案是:先描述,在組織。地址空間的本質(zhì):是內(nèi)核的一種數(shù)據(jù)結(jié)構(gòu)(mm_struct)。簡(jiǎn)單來說,我們的虛擬地址空間會(huì)被一個(gè)名為?struct mm_struct的數(shù)據(jù)結(jié)構(gòu)管理起來。


三、進(jìn)程地址空間基礎(chǔ)

1.相關(guān)的基礎(chǔ)概念

注意:本次講解以32位計(jì)算機(jī)平臺(tái)為基礎(chǔ)

?在正式深入學(xué)習(xí)進(jìn)程地址空間之前,我們需要先了解一些相關(guān)的基礎(chǔ)概念:

  1. 進(jìn)程/內(nèi)存空間描述的基本空間大小為字節(jié);
  2. 32位下計(jì)算機(jī)最多可以形成 2^32個(gè)地址;
  3. 每個(gè)地址標(biāo)識(shí)一個(gè)字節(jié),所以我們能表示的地址空間范圍最大為 4G;
  4. 每個(gè)進(jìn)程都要有唯一的地址,假設(shè)我們需要表示 2^32個(gè)地址,我們需要保持每個(gè)地址的唯一性;
  5. 我們可以通過 32位的數(shù)據(jù)(32個(gè)比特位的數(shù)據(jù))來表示一個(gè)地址。

進(jìn)程地址空間圖例如下?

【Linux初階】進(jìn)程地址空間 | CUP與可執(zhí)行程序的交互原理


2.區(qū)域劃分與調(diào)整

這里我們舉一個(gè)例子來理解區(qū)域劃分和區(qū)域調(diào)整。

假設(shè)初中有一對(duì)男女同桌,由于男生太貪玩,經(jīng)常打擾到旁邊的女生學(xué)習(xí),所以女生給桌子畫了一條線,將桌子分成了兩個(gè)區(qū)域,假設(shè)桌子有100cm,她將區(qū)域劃分為[1-50, 51-100],這就是區(qū)域劃分。

而后小男孩還是不在意,經(jīng)常越線,因此小女孩調(diào)整了桌子上線的位置,桌子有100厘米,但是女孩只給了小男孩30厘米的活動(dòng)范圍,[1-30, 31-100],這種在劃分后調(diào)整各自區(qū)域的行為稱為區(qū)域調(diào)整。?

通過觀察下圖我們可以發(fā)現(xiàn),只要我們調(diào)整不同對(duì)象的 start、end,就可以實(shí)現(xiàn)區(qū)域調(diào)整(擴(kuò)大 or 縮小)。

【Linux初階】進(jìn)程地址空間 | CUP與可執(zhí)行程序的交互原理

我們可以通過搜索不同的地址位置,找到數(shù)據(jù)所在。還是上面的例子來解釋,可能1-10cm中放有小男孩的筆袋,12-16cm放有小男孩的筆記本。

———— 我是一條知識(shí)分割線 ————?

之前文章中提到,我們可以通過 32位的數(shù)據(jù)(32個(gè)比特位的數(shù)據(jù))來表示地址,我們的虛擬地址空間會(huì)被一個(gè)名為?struct mm_struct的數(shù)據(jù)結(jié)構(gòu)管理起來。在32位計(jì)算機(jī)下,通常我們采用 int類型的數(shù)據(jù)來記錄一個(gè)地址,因?yàn)?int在剛好在32位計(jì)算機(jī)下占32個(gè)比特位。在?struct mm_struct的數(shù)據(jù)結(jié)構(gòu)中包含著不同區(qū)域地址信息,其中就包含有堆的區(qū)域起始地址、區(qū)域結(jié)束地址等。

這些在不同的區(qū)域范圍內(nèi)、可以供我們使用的地址稱為虛擬地址。也就是說在地址空間中的 2^32個(gè)地址都是虛擬地址。

所以,進(jìn)程地址空間也叫做進(jìn)程虛擬地址空間,它的本質(zhì)實(shí)際上是一個(gè)存儲(chǔ)虛擬地址及其相關(guān)數(shù)據(jù)的集合。

【Linux初階】進(jìn)程地址空間 | CUP與可執(zhí)行程序的交互原理

———— 我是一條知識(shí)分割線 ————

在地址空間中,代碼區(qū)(已初始化、未初始化)的大小是固定的,也就是說代碼區(qū)的起始和結(jié)束地址不可被調(diào)整;但是堆區(qū)和棧區(qū)不同,堆區(qū)可以通過 malloc等手段調(diào)整它的大小,棧區(qū)也可以定義相應(yīng)的局部變量,也就是說,堆區(qū)和棧區(qū)是可以被調(diào)整的!

heap & stack的調(diào)整,本質(zhì)上就是調(diào)整兩個(gè)區(qū)域的 start和end。在我們的編程過程中,定義局部變量,malloc、new對(duì)象實(shí)際上就是擴(kuò)大堆區(qū)或者棧區(qū)。當(dāng)我們 free的時(shí)候,實(shí)際上就是在縮小堆區(qū)或者棧區(qū)。

3.程序是如何更改內(nèi)存中的數(shù)據(jù)的?

在第一節(jié)中我們驗(yàn)證過,父子進(jìn)程,輸出地址是一致的,但是變量?jī)?nèi)容不一樣,這到底是怎么做到的呢?在解答這個(gè)問題之前,我們先要知道,程序是如何更改內(nèi)存中的數(shù)據(jù)的。接下來這一部分的知識(shí)主要就是向大家講解,程序是如何更改內(nèi)存中的數(shù)據(jù)的。

文章第二節(jié)講到,操作系統(tǒng)會(huì)為進(jìn)程畫“大餅”,這里的大餅就是地址空間(mm_struct),因此相應(yīng)的,tack_struct(PCB,進(jìn)程控制塊)會(huì)有相應(yīng)的指針指向進(jìn)程地址空間。

【Linux初階】進(jìn)程地址空間 | CUP與可執(zhí)行程序的交互原理

———— 我是一條知識(shí)分割線 ————?

在硬件方面(內(nèi)存和磁盤),假設(shè)有文件 my.exe存在于磁盤之中,當(dāng)文件加載到內(nèi)存中,占用內(nèi)存 1k字節(jié)的空間,每個(gè)字節(jié)我們都可將它視作一個(gè)地址。

內(nèi)存在使用時(shí),它會(huì)和我們對(duì)應(yīng)的磁盤進(jìn)行輸入輸出數(shù)據(jù),這個(gè)工作我們稱為 IO,其中傳輸數(shù)據(jù)的基本單位為 4KB(1KB = 1024字節(jié))。在此基礎(chǔ)上,內(nèi)存可以被我們劃分為一個(gè)個(gè) 4KB大小空間塊,這個(gè)空間塊我們稱之為 page(頁),如果我們將內(nèi)存想象為一個(gè)大數(shù)組,則內(nèi)存大小或者說對(duì)應(yīng)的頁有:struct page men[4GB/4KB]。只要我們知道某一頁的起始地址,再加上對(duì)應(yīng)的偏移量,我們就可以找到內(nèi)存的任意一個(gè)地址。

【Linux初階】進(jìn)程地址空間 | CUP與可執(zhí)行程序的交互原理

———— 我是一條知識(shí)分割線 ————?

頁表簡(jiǎn)介:可以用于建立虛擬地址和物理地址之間的映射關(guān)系,實(shí)現(xiàn)虛擬地址和物理地址的轉(zhuǎn)換。頁表內(nèi)部不是簡(jiǎn)單的對(duì)應(yīng)空間結(jié)構(gòu),因?yàn)槿绻@樣設(shè)計(jì)需要占用 4G*8 = 32G。左式中8的含義 - 假設(shè)空間為1-1對(duì)應(yīng)結(jié)構(gòu),左邊和右邊各一個(gè)數(shù)據(jù),一個(gè)數(shù)據(jù)需要4個(gè)字節(jié)表示(int),加起來則需要8個(gè)字節(jié)。因此,頁表內(nèi)部使用的是多級(jí)頁表的結(jié)構(gòu),就是頁目錄為根,對(duì)應(yīng)多個(gè)二級(jí)、三級(jí)索引這樣的結(jié)構(gòu),這里就不展開細(xì)說了。

【Linux初階】進(jìn)程地址空間 | CUP與可執(zhí)行程序的交互原理

下圖中以淺藍(lán)色標(biāo)記為例,虛擬地址0x123445678可以通過頁表映射找到對(duì)應(yīng)的物理地址 0x11112222,物理空間中儲(chǔ)存著 val變量的值為10.

【Linux初階】進(jìn)程地址空間 | CUP與可執(zhí)行程序的交互原理

———— 我是一條知識(shí)分割線 ————?

?以下述代碼為例講述程序是如何更改內(nèi)存中的數(shù)據(jù)的?

char val = 100;

首先我們要明確,val的地址是虛擬地址(在第一節(jié)中驗(yàn)證過),當(dāng)代碼運(yùn)行起來時(shí),操作系統(tǒng)拿著 val的虛擬地址,去查找頁表,找到對(duì)應(yīng)的物理地址,將物理地址對(duì)應(yīng)內(nèi)存空間中的數(shù)值修改/存儲(chǔ)為100。至此我們已經(jīng)可以充分認(rèn)識(shí)到程序是如何更改內(nèi)存中的數(shù)據(jù)的原理了。

注意:這個(gè)過程都是由操作系統(tǒng)完成的!

4.操作系統(tǒng)會(huì)根據(jù)進(jìn)程的需求分配虛擬地址空間

進(jìn)程無法直接訪問物理內(nèi)存,進(jìn)程只能通過虛擬地址空間來訪問對(duì)應(yīng)的數(shù)據(jù),其中我們可以認(rèn)為操作系統(tǒng)給進(jìn)程畫了一個(gè)“大餅”(紅色正方形框框),每個(gè)進(jìn)程都以為自己能占有 2^32個(gè)地址空間(內(nèi)存大?。?。

【Linux初階】進(jìn)程地址空間 | CUP與可執(zhí)行程序的交互原理

而實(shí)際上,我們通過觀察,發(fā)現(xiàn)堆和棧之間還有很大部分的空缺,不難推斷出,操作系統(tǒng)會(huì)根據(jù)進(jìn)程對(duì)應(yīng)的需求給進(jìn)程分配地址空間,而不會(huì)真的將所有空間都給一個(gè)進(jìn)程。相反,如果進(jìn)程的需求不合理,操作系統(tǒng)會(huì)拒絕進(jìn)程的對(duì)應(yīng)訪問

【Linux初階】進(jìn)程地址空間 | CUP與可執(zhí)行程序的交互原理


四、為什么存在地址空間?

1.防止非法越界訪問

如果進(jìn)程直接訪問物理內(nèi)存,會(huì)存在越界非法操作的風(fēng)險(xiǎn)(比如將儲(chǔ)存有別的數(shù)據(jù)的page覆蓋)

地址空間的存在,使程序員在應(yīng)用層只能通過頁表映射來訪問物理地址,期間操作系統(tǒng)可以幫我們甄別相應(yīng)指令,接收正確指令,拒絕錯(cuò)誤訪問。

2.方便進(jìn)程解耦,保證進(jìn)程獨(dú)立性

進(jìn)程地址空間的存在,可以更方便的讓進(jìn)程與進(jìn)程之間的數(shù)據(jù)進(jìn)行解耦,保證進(jìn)程獨(dú)立性

進(jìn)程具有獨(dú)立性,一個(gè)進(jìn)程對(duì)被共享的數(shù)據(jù)進(jìn)行修改,不能影響其他進(jìn)程

操作系統(tǒng)為了保證進(jìn)程獨(dú)立性,當(dāng)物理內(nèi)存中的一個(gè)共享數(shù)據(jù)需要被修改時(shí),操作系統(tǒng)會(huì)在物理內(nèi)存中開辟一個(gè)新的空間,數(shù)據(jù)拷貝一份放到新的空間中,然后會(huì)將頁表原來對(duì)應(yīng)共享數(shù)據(jù)空間物理地址改為新空間的地址(更改映射)。這樣,在進(jìn)程改變某個(gè)值的時(shí)候,就只和這個(gè)進(jìn)程本身有關(guān),和其他進(jìn)程無關(guān),實(shí)現(xiàn)了進(jìn)程之間的相互獨(dú)立。

任何一方嘗試寫入,OS先進(jìn)行數(shù)據(jù)拷貝,更改頁表映射,然后再讓進(jìn)程進(jìn)行修改,我們把這樣的行為稱為寫時(shí)拷貝。在我們修改數(shù)據(jù)時(shí),操作系統(tǒng)會(huì)幫我們自動(dòng)完成寫時(shí)拷貝。

寫時(shí)拷貝,幫我們實(shí)現(xiàn)了數(shù)據(jù)間的分離。以下圖為例,在數(shù)據(jù)不做修改時(shí),父子進(jìn)程可以共用同一塊物理內(nèi)存空間,當(dāng)子進(jìn)程對(duì)數(shù)據(jù)進(jìn)行修改,操作系統(tǒng)會(huì)通過寫時(shí)拷貝,實(shí)現(xiàn)數(shù)據(jù)分離,即父進(jìn)程的 g_val變量和子進(jìn)程 g_val變量存儲(chǔ)于不同的物理地址空間中。

【Linux初階】進(jìn)程地址空間 | CUP與可執(zhí)行程序的交互原理

每個(gè)進(jìn)程都有自己獨(dú)立的內(nèi)核數(shù)據(jù)結(jié)構(gòu),包括獨(dú)立的PCB、獨(dú)立的地址空間、獨(dú)立的頁表。

結(jié)論:進(jìn)程 = 進(jìn)程的內(nèi)核數(shù)據(jù)結(jié)構(gòu) + 進(jìn)程對(duì)應(yīng)的代碼和數(shù)據(jù),當(dāng)進(jìn)程內(nèi)核數(shù)據(jù)結(jié)構(gòu)和對(duì)應(yīng)數(shù)據(jù)都相互獨(dú)立時(shí),這個(gè)進(jìn)程也就和其他進(jìn)程相互獨(dú)立了。也就是說,地址空間的存在,使進(jìn)程可以擁有獨(dú)立的內(nèi)核數(shù)據(jù)結(jié)構(gòu),可以更方便的讓進(jìn)程與進(jìn)程之間的數(shù)據(jù)進(jìn)行解耦,保證進(jìn)程獨(dú)立性。

3.統(tǒng)一編譯,方便使用

讓進(jìn)程可以以統(tǒng)一的視角,來看待代碼和數(shù)據(jù)的各個(gè)區(qū)域,方便使用;方便編譯器也以統(tǒng)一的視角來編譯代碼,編完可以直接用。

(1)可執(zhí)行文件中有地址嗎?

我們的可執(zhí)行文件中,有沒有地址呢?答案是有的,我們的可執(zhí)行文件中早就有地址了!這種在程序內(nèi)部使用的地址,我們稱它們?yōu)?- 邏輯地址。程序可以通過邏輯地址實(shí)現(xiàn)內(nèi)部之間的相互跳轉(zhuǎn),實(shí)現(xiàn)函數(shù)調(diào)用等功能。

(2)編譯器的編碼方式

編譯器在編譯我們的代碼和數(shù)據(jù)時(shí),會(huì)按照虛擬地址空間的方式給我們的代碼和數(shù)據(jù)進(jìn)行編址,也就是它也會(huì)按照32位的方式進(jìn)行編址。

只有??臻g、堆空間對(duì)應(yīng)的數(shù)據(jù)沒有進(jìn)行編址,因?yàn)樗鼈兪切枰趦?nèi)存中動(dòng)態(tài)申請(qǐng)的。其他的代碼都會(huì)完成編址。

(3)物理地址的來源

程序內(nèi)部使用的地址(邏輯地址),在程序加載到內(nèi)存時(shí),會(huì)天然具有物理地址。因?yàn)檫壿嫷刂泛臀锢淼刂返谋硎痉椒ㄏ嗤?,所以邏輯地址就是物理地址,不用改變。只不過我們?yōu)槌绦騼?nèi)部的地址起了一個(gè)名稱 - 邏輯地址,加以辨識(shí)罷了。

注意通常情況下,邏輯地址、物理地址、虛擬地址的表示方式是一樣的,都采用32位的數(shù)據(jù)進(jìn)行記錄。這也就是為什么編譯器可以以統(tǒng)一的視角來編譯代碼,編完可以直接用的原因所在。

【Linux初階】進(jìn)程地址空間 | CUP與可執(zhí)行程序的交互原理

———— 我是一條知識(shí)分割線 ————

(4)CPU與可執(zhí)行程序交互的原理

代碼編譯好加載到內(nèi)存后,會(huì)生成對(duì)應(yīng)的虛擬地址,且在內(nèi)存中的代碼天然具有物理地址。操作系統(tǒng)會(huì)用?main函數(shù)入口和結(jié)束處的虛擬地址等數(shù)據(jù),初始化進(jìn)程虛擬地址空間(主要是代碼區(qū))和進(jìn)程對(duì)應(yīng)的頁表,再將虛擬地址空間初始化好的地址加載到CPU的寄存器中。

CPU通過虛擬地址,經(jīng)過頁表映射,找到對(duì)應(yīng)物理地址中數(shù)據(jù)并進(jìn)行獲取。CPU讀進(jìn)來的都是指令,指令中包含地址,這里的地址是虛擬地址。

CPU處理完數(shù)據(jù)之后,再將數(shù)據(jù)通過虛擬地址,經(jīng)過頁表映射,寫入到對(duì)應(yīng)物理地址的內(nèi)存中

具體圖示如下,下圖中的地址都是虛擬地址(物理內(nèi)存中的虛擬地址來源于代碼編譯生成的虛擬地址)

【Linux初階】進(jìn)程地址空間 | CUP與可執(zhí)行程序的交互原理

所以,在整個(gè)訪問過程中,CPU輸入輸出的都是虛擬地址,CPU壓根兒就沒有見到物理地址,也即是說CPU不會(huì)對(duì)物理地址進(jìn)行直接訪問。

在我們對(duì)代碼進(jìn)行 debug(調(diào)試)時(shí),程序已經(jīng)運(yùn)行起來了,此時(shí)我們通過監(jiān)視窗口看到寄存器相關(guān)的地址都是虛擬地址。

總結(jié):虛擬進(jìn)程地址的使用,讓進(jìn)程可以以統(tǒng)一的視角,來看待代碼和數(shù)據(jù)的各個(gè)區(qū)域,方便使用;

———— 我是一條知識(shí)分割線 ————

(5)邏輯地址知識(shí)補(bǔ)充

注意:Linux下我們編譯可執(zhí)行程序的格式的編碼格式為 ELF

邏輯地址有兩種常見的編址方式,一種是線性編址方式,另一種是區(qū)域編址方式。這兩種生成的都是邏輯地址,但是因?yàn)?span style="color:#4da8ee;">線性編址編出來的地址和物理地址的表示方法相同,因此當(dāng)程序內(nèi)部使用線性編址時(shí),在程序加載到內(nèi)存之后,該程序就天然具有了物理地址。

  • 線性編址(常用)

地址從0開始,假設(shè)普通代碼占了100個(gè)字節(jié)(每個(gè)字節(jié)一個(gè)地址),那么其他數(shù)據(jù)代碼從101個(gè)地址開始,繼續(xù)向下呈線性編址

【Linux初階】進(jìn)程地址空間 | CUP與可執(zhí)行程序的交互原理

  • 區(qū)域編址(不常用 - 了解)

區(qū)域編址,采用的是區(qū)域起始地址加偏移量的方式,當(dāng)代碼加載到內(nèi)存時(shí),每一個(gè)地址都要做修改才能轉(zhuǎn)換成對(duì)應(yīng)的物理地址。因?yàn)檫@種編制方式,使得地址時(shí)一塊塊區(qū)域區(qū)分開來的,我們可以使用物理地址的起始地址+對(duì)應(yīng)的偏移量,找到對(duì)應(yīng)邏輯地址。

地址從0開始,代碼區(qū)的普通代碼編址完成后,數(shù)據(jù)區(qū)的地址重新從0開始編址,呈現(xiàn)了區(qū)域性。

【Linux初階】進(jìn)程地址空間 | CUP與可執(zhí)行程序的交互原理


結(jié)語?

?????Linux進(jìn)程地址空間 的知識(shí)大概就講到這里啦,博主后續(xù)會(huì)繼續(xù)更新更多Linux操作系統(tǒng)的相關(guān)知識(shí),干貨滿滿,如果覺得博主寫的還不錯(cuò)的話,希望各位小伙伴不要吝嗇手中的三連哦!你們的支持是博主堅(jiān)持創(chuàng)作的動(dòng)力!?????文章來源地址http://www.zghlxwxcb.cn/news/detail-453606.html

到了這里,關(guān)于【Linux初階】進(jìn)程地址空間 | CUP與可執(zhí)行程序的交互原理的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Linux: 進(jìn)程地址空間究竟是什么?進(jìn)程地址空間存在意義何在?

    Linux: 進(jìn)程地址空間究竟是什么?進(jìn)程地址空間存在意義何在?

    ?在C/C++中,我們常將內(nèi)存分為: 代碼區(qū)、常量區(qū)、全局區(qū)(靜態(tài)區(qū))、堆、棧 等等。相關(guān)內(nèi)存區(qū)域劃分如下:(X86, 32位平臺(tái)) 如何驗(yàn)證C/C++中各區(qū)域的相對(duì)位置呢? ?我們可以在每個(gè)區(qū)域中選擇一個(gè)地址來驗(yàn)證C/C++中各區(qū)域的相對(duì)位置!!具體如下: 【源代碼】: 【運(yùn)行

    2024年04月08日
    瀏覽(26)
  • 每天40min,我們一起用70天穩(wěn)扎穩(wěn)打?qū)W完《JavaEE初階》——1/70 第一天【進(jìn)程和線程】【虛擬地址空間】

    專注 效率 記憶 預(yù)習(xí) 筆記 復(fù)習(xí) 做題 歡迎觀看我的博客,如有問題交流,歡迎評(píng)論區(qū)留言,一定盡快回復(fù)?。ù蠹铱梢匀タ次业膶冢撬形恼碌哪夸洠?文章字體風(fēng)格: 紅色文字表示:重難點(diǎn)★? 藍(lán)色文字表示:思路以及想法★? 如果大家覺得有幫助的話,感謝大家?guī)?/p>

    2024年02月15日
    瀏覽(24)
  • Linux之進(jìn)程(四)(進(jìn)程地址空間)

    Linux之進(jìn)程(四)(進(jìn)程地址空間)

    目錄 一、程序地址空間 二、進(jìn)程地址空間 1、概念 2、寫時(shí)拷貝 3、為什么要有進(jìn)程地址空間 四、總結(jié) 我們先來看看下面這張圖。這張圖是我們?cè)趯W(xué)習(xí)語言時(shí)就見到過的內(nèi)存區(qū)域劃分圖。? 下面我們?cè)贚inux下看一看內(nèi)存區(qū)域是不是也是這么劃分的。 可見在Linux下也是符合上面

    2024年02月04日
    瀏覽(23)
  • 【Linux】進(jìn)程>環(huán)境變量&&地址空間&&進(jìn)程調(diào)度

    【Linux】進(jìn)程>環(huán)境變量&&地址空間&&進(jìn)程調(diào)度

    主頁: 醋溜馬桶圈-CSDN博客 專欄: Linux_醋溜馬桶圈的博客-CSDN博客 gitee :mnxcc (mnxcc) - Gitee.com 目錄 1.環(huán)境變量 1.1 基本概念 1.2 常見環(huán)境變量? 1.3 查看環(huán)境變量方法? 1.4?和環(huán)境變量相關(guān)的命令 1.5 環(huán)境變量的組織方式 1.6 通過代碼如何獲取環(huán)境變量 1.6.1 命令行第三個(gè)參數(shù) 1

    2024年04月15日
    瀏覽(28)
  • 【Linux】進(jìn)程周邊006之進(jìn)程地址空間

    【Linux】進(jìn)程周邊006之進(jìn)程地址空間

    ? ?? 樊梓慕: 個(gè)人主頁 ??? 個(gè)人專欄: 《C語言》 《數(shù)據(jù)結(jié)構(gòu)》 《藍(lán)橋杯試題》 《LeetCode刷題筆記》 《實(shí)訓(xùn)項(xiàng)目》 《C++》 《Linux》 ?? 每一個(gè)不曾起舞的日子,都是對(duì)生命的辜負(fù) 目錄 前言 1.程序地址空間 1.1驗(yàn)證地址空間的排布 ?1.2利用fork函數(shù)觀察當(dāng)子進(jìn)程修改某個(gè)共

    2024年02月04日
    瀏覽(43)
  • 【Linux】—— 進(jìn)程地址空間

    【Linux】—— 進(jìn)程地址空間

    序言: 在上篇中,我們講解了關(guān)于進(jìn)程優(yōu)先級(jí)的概念。本期,我將給大家介紹的是關(guān)于進(jìn)程地址空間的話題。 目錄 (一)程序地址空間回顧 (二)代碼演示 (三)進(jìn)程地址空間的引入 總結(jié) 我們?cè)趯W(xué)習(xí)C/C++語言的時(shí)候,大家可能都見過這樣的空間布局圖: 一個(gè)程序有哪些

    2024年02月15日
    瀏覽(25)
  • 【Linux】深挖進(jìn)程地址空間

    【Linux】深挖進(jìn)程地址空間

    作者簡(jiǎn)介:?舊言~,目前大二,現(xiàn)在學(xué)習(xí)Java,c,c++,Python等 座右銘:松樹千年終是朽,槿花一日自為榮。 目標(biāo):熟悉【Linux】進(jìn)程地址空間 毒雞湯:也許有一天,你發(fā)覺日子特別的艱難,那可能是這次的收獲特別的巨大。 望小伙伴們點(diǎn)贊??收藏?加關(guān)注喲????? ????

    2024年02月03日
    瀏覽(26)
  • 【Linux】理解進(jìn)程地址空間

    【Linux】理解進(jìn)程地址空間

    ?? 作者: 阿潤(rùn)菜菜 ?? 專欄: Linux系統(tǒng)編程 ?我們?cè)趯W(xué)習(xí)C語言的時(shí)候,都學(xué)過內(nèi)存區(qū)域的劃分如棧、堆、代碼區(qū)、數(shù)據(jù)區(qū)這些。但我們其實(shí)并不真正理解內(nèi)存 — 我們之前一直說的內(nèi)存是物理上的內(nèi)存嗎? 我們先看一段測(cè)試代碼: 運(yùn)行結(jié)果: 我們可以注意到子進(jìn)程的變量

    2024年02月02日
    瀏覽(28)
  • Linux--進(jìn)程地址空間

    Linux--進(jìn)程地址空間

    1.線程地址空間 所謂進(jìn)程地址空間(process address space),就是從進(jìn)程的視角看到的地址空間,是進(jìn)程運(yùn)行時(shí)所用到的虛擬地址的集合。 簡(jiǎn)單地說,進(jìn)程就是內(nèi)核數(shù)據(jù)結(jié)構(gòu)和代碼和本身的代碼和數(shù)據(jù),進(jìn)程本身不能訪問物理地址,之時(shí)候就需要有一個(gè)中間媒介,就是地址空間,

    2024年02月11日
    瀏覽(21)
  • Linux:進(jìn)程地址空間

    Linux:進(jìn)程地址空間

    目錄 1.程序地址空間? 2.進(jìn)程地址空間 我們?cè)谥vC/C++語言的時(shí)候,32位平臺(tái)下,我們見過這樣的空間布局圖 我們來驗(yàn)證一下這張圖的正確性: 運(yùn)行結(jié)果: 通過觀察靜態(tài)變量的位置,可以認(rèn)為靜態(tài)變量就是全局變量,只是靜態(tài)變量只初始化一次,有作用域的限制。 這里棧區(qū)還

    2024年02月04日
    瀏覽(28)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包