www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁 > 公眾號(hào)精選 > IOT物聯(lián)網(wǎng)小鎮(zhèn)
[導(dǎo)讀]幾個(gè)重要的段寄存器Linux2.6中的線性地址區(qū)間一個(gè)“完整”的8086匯編程序前兩篇文章,我們一起學(xué)習(xí)了8086處理器中關(guān)于CPU、內(nèi)存的基本使用方式,重點(diǎn)對(duì)段寄存器和內(nèi)存的尋址方式進(jìn)行了介紹??赡苡行┬』锇闀?huì)對(duì)此不屑:現(xiàn)在都是多核的現(xiàn)代處理器,操作系統(tǒng)已經(jīng)變得非常的強(qiáng)大,為何...


  • 幾個(gè)重要的段寄存器

  • Linux 2.6 中的線性地址區(qū)間

  • 一個(gè)“完整”的 8086 匯編程序


前兩篇文章,我們一起學(xué)習(xí)了 8086 處理器中關(guān)于 CPU、內(nèi)存的基本使用方式,重點(diǎn)對(duì)段寄存器和內(nèi)存的尋址方式進(jìn)行了介紹。

可能有些小伙伴會(huì)對(duì)此不屑:現(xiàn)在都是多核的現(xiàn)代處理器,操作系統(tǒng)已經(jīng)變得非常的強(qiáng)大,為何還去學(xué)習(xí)這些古董知識(shí)?

前幾天看到下面這段話,可以來回答這個(gè)問題:

“我們都希望學(xué)習(xí)最新的、使用的東西,但學(xué)習(xí)的過程是客觀的?!?/p>“任何合理的學(xué)習(xí)過程(盡可能排除走彎路、盲目探索、不成系統(tǒng))都是一個(gè)循序漸進(jìn)的過程?!?/p>“我們必須先通過一個(gè)易于全面把握的事物,來學(xué)習(xí)和探索一般的規(guī)律和方法?!?/p>就拿學(xué)習(xí) Linux 操作系統(tǒng)來說,作為一個(gè)長期的學(xué)習(xí)計(jì)劃,不太可能一上來就閱讀最新的 Linux 5.13 版本的代碼。

更有可能是先學(xué)習(xí) 0.11 版本,理解了其中的一些原理、思想之后,再循序漸進(jìn)的向高版本進(jìn)行學(xué)習(xí)、探索。

那么對(duì)于 《Linux 從頭學(xué)》這個(gè)系列的文章來說,我是希望自己能夠把學(xué)習(xí)路線再拉長一些,從更底層的硬件機(jī)制、驅(qū)動(dòng)原理開始,由簡(jiǎn)入繁,一步一步最終把 Linux 操作系統(tǒng)這個(gè)塊硬骨頭給啃下來。

那么今天我們就繼續(xù) 8086 下的學(xué)習(xí),來看看一個(gè)相對(duì)“完整”程序的基本結(jié)構(gòu)。

幾個(gè)重要的段寄存器

x86 系統(tǒng)中,段尋址機(jī)制以及相關(guān)的寄存器是如此的重要,以至于我忍不住在這里,把幾個(gè)段寄存器再小結(jié)一下。

Linux從頭學(xué)03:如何告訴 CPU,代碼段、數(shù)據(jù)段、棧段在內(nèi)存中什么位置?
代碼段:用來存放代碼,段的基地址放在寄存器 CS 中,指令指針寄存器 IP 用來表示下一條指令在段中的偏移地址;

數(shù)據(jù)段:用來存放程序處理的數(shù)據(jù),段的基地址存放在寄存器 DS 中。對(duì)數(shù)據(jù)段中的某個(gè)數(shù)據(jù)進(jìn)行操作時(shí),直接在匯編代碼中通過立即數(shù)或寄存器來指定偏移地址;

棧段:本質(zhì)上也是用來存放數(shù)據(jù),只不過它的操作方式比較特殊而已:通過 PUSH 和 POP 指令來進(jìn)行操作。段的基地址存放在寄存器 SS 中,棧頂單元的偏移地址存放在寄存器 IP 中。

這里的段,本質(zhì)上是我們把內(nèi)存上的某一塊連續(xù)的存儲(chǔ)空間,專門存儲(chǔ)某一類的數(shù)據(jù)。

我們之所以能夠這么做,是因?yàn)?CPU 通過以上幾個(gè)寄存器,讓我們這樣的“安排”稱為一種可能。

一句話總結(jié):CPU 將內(nèi)存中的某個(gè)段的內(nèi)容當(dāng)做代碼,是因?yàn)?CS:IP 指向了那里;CPU 將某個(gè)段當(dāng)做棧,是因?yàn)?CS:SP 指向了那里。

在之前的一篇文章中,演示了?ELF 格式的可執(zhí)行文件中,具體包含了哪些段《Linux系統(tǒng)中編譯、鏈接的基石-ELF文件:扒開它的層層外衣,從字節(jié)碼的粒度來探索》:

Linux從頭學(xué)03:如何告訴 CPU,代碼段、數(shù)據(jù)段、棧段在內(nèi)存中什么位置?
雖然這張圖中描述的段結(jié)構(gòu)更復(fù)雜,但是從本質(zhì)上來說,它與 8086 中描述的段結(jié)構(gòu)是一樣的!

Linux 2.6 中的線性地址區(qū)間

在一個(gè)現(xiàn)代操作系統(tǒng)中,一個(gè)進(jìn)程中使用的的地址空間,一般稱作虛擬地址(也稱作邏輯地址)。

虛擬地址首先經(jīng)過段轉(zhuǎn)換,得到線性地址;然后線性地址再經(jīng)過分頁轉(zhuǎn)換,得到最終的物理地址。

Linux從頭學(xué)03:如何告訴 CPU,代碼段、數(shù)據(jù)段、棧段在內(nèi)存中什么位置?
這里再啰嗦一下,很多書籍中隊(duì)內(nèi)存地址的稱呼比較多,都是根據(jù)作者的習(xí)慣來稱呼。

我是按照上圖的方式來理解的: ?編譯器產(chǎn)生的地址叫做虛擬地址,也叫做邏輯地址,然后經(jīng)過兩級(jí)轉(zhuǎn)換,得到最終的物理地址。

Linux 2.6 代碼中,由于 Linux 把整個(gè) 4 GB 的地址空間當(dāng)做一個(gè)“扁平”的結(jié)果來處理(段的基地址是 0x0000_0000,偏移地址的最大值是 4GB),因此虛擬地址(邏輯地址)在數(shù)值上等于線性地址。

我們?cè)俳Y(jié)合上次給出的這張圖來理解:

Linux從頭學(xué)03:如何告訴 CPU,代碼段、數(shù)據(jù)段、棧段在內(nèi)存中什么位置?
這張圖的意思是:在 Linux 2.6 中,用戶代碼段的開始地址是 0,最大范圍是 4 GB;用戶數(shù)據(jù)段的開始地址是 0,最大范圍也是 4 GB;內(nèi)核的數(shù)據(jù)段和代碼段也是如此。

Linux從頭學(xué)03:如何告訴 CPU,代碼段、數(shù)據(jù)段、棧段在內(nèi)存中什么位置?
為什么:虛擬地址(邏輯地址)在數(shù)值上等于線性地址?

線性地址 = 段基址 虛擬地址(偏移量),因?yàn)槎位窞?0 ,所以線性地址在數(shù)值上等于虛擬地址。

Linux 之所以要這樣安排,是因?yàn)樗?span>不想過多的利用 x86 提供的段機(jī)制來進(jìn)行內(nèi)存地址的管理,而是想充分利用分頁機(jī)制來進(jìn)行更加靈活的地址管理。

還有一點(diǎn)需要提醒一下:

在上述描述的文字中,我都會(huì)標(biāo)明一個(gè)機(jī)制或者策略,它是由 x86 平臺(tái)提供的,還是由 Linux 操作系統(tǒng)提供的。

對(duì)于分頁機(jī)制也是如此,x86 硬件提供了分頁機(jī)制,但是 Linuxx86 提供的這個(gè)分頁機(jī)制的基礎(chǔ)上,進(jìn)行了擴(kuò)展,以達(dá)到更加靈活的內(nèi)存地址管理目的。

因此,各位小伙伴在看一些書籍的時(shí)候,心中要有一個(gè)譜:當(dāng)前描述內(nèi)容的上下文環(huán)境是什么。

當(dāng)我們創(chuàng)建一個(gè)進(jìn)程的時(shí)候,在內(nèi)核中就會(huì)記錄這個(gè)進(jìn)程所擁有的所有線性地址區(qū)間。

進(jìn)程所擁有的所有線性地址區(qū)間是一個(gè)動(dòng)態(tài)的過程,根據(jù)程序的需求隨時(shí)進(jìn)行擴(kuò)展或縮小。例如:把一個(gè)文件映射到內(nèi)存,動(dòng)態(tài)加載/卸載一個(gè)動(dòng)態(tài)庫等等。

我們知道,內(nèi)核在操作物理內(nèi)存的時(shí)候,是通過“頁框”這個(gè)單位來管理的。

Linux從頭學(xué)03:如何告訴 CPU,代碼段、數(shù)據(jù)段、棧段在內(nèi)存中什么位置?
一個(gè)頁框可以包含 1-n 個(gè)頁,每一頁的大小一般是 4 KB,這是對(duì)物理內(nèi)存的管理。

一個(gè)線性地址區(qū)間可以包含多個(gè)物理頁。每一個(gè)線性地址最終通過多級(jí)的頁表轉(zhuǎn)換,來最終得到一個(gè)物理地址。

注意:上圖中,線性地址區(qū)間1,映射到物理地址空間中的 N 個(gè) Page,這些 Page 有可能是連續(xù)的,也有可能不是連續(xù)的。

雖然在物理內(nèi)存中是不連續(xù)的,但是由于被分頁轉(zhuǎn)換機(jī)制進(jìn)行了屏蔽,我們?cè)趹?yīng)用程序中都是按照連續(xù)的空間來使用的。

一個(gè)“完整”的 8086 匯編程序

我們?cè)倮^續(xù)回到 8086 系統(tǒng)中來。

這里描述的地址,經(jīng)過段地址轉(zhuǎn)換之后,就是一個(gè)物理地址,沒有經(jīng)過復(fù)雜的頁表轉(zhuǎn)換。

這也是我們以 8086 系統(tǒng)作為學(xué)習(xí)平臺(tái)的目的:拋開復(fù)雜的操作系統(tǒng),直接探索底層的東西。

在這個(gè)最簡(jiǎn)單的匯編程序中,會(huì)使用到 3 個(gè)段:代碼段,數(shù)據(jù)段和棧段。

前面已經(jīng)說到:所謂的段,就是一個(gè)地址空間。既然是一個(gè)地址空間,必然包含 2 個(gè)元素:從什么地方開始,長度是多少。

還是直接上代碼:

assume ds:addr1, ss:addr2, cs:addr3

addr1 segment ; 把數(shù)據(jù)段安排在這個(gè)位置
db 32 dup (0) ; 這 32 個(gè)字節(jié),是數(shù)據(jù)段的大小
addr1 end

addr2 segment ; 把棧段安排在這個(gè)位置
db 32 dup(0) ; 這 32 個(gè)字節(jié),是棧段的大小
addr2 end

addr3 segment ; 把代碼段安排在這個(gè)位置
start
mov ax, addr1
mov ds, ax ; 設(shè)置數(shù)據(jù)段寄存器

mov ax, addr2
mov ss, ax ; 設(shè)置棧段寄存器
mov sp, 20h ; 設(shè)置棧頂指針寄存器

... ; 其他代碼
addr3 ends

end start
以上就是一個(gè)匯編代碼的基本程序結(jié)構(gòu),我們給它安排了 3 個(gè)段。

3 個(gè)標(biāo)號(hào):addr1、addr2addr3,代表了每一個(gè)段的開始地址。在代碼段的開始部分,把數(shù)據(jù)段標(biāo)號(hào) addr1 代表的地址,賦值給 DS 寄存器;把棧段標(biāo)號(hào) addr2 代表的地址,賦值給 SS 寄存器。

這里的標(biāo)號(hào),是不是與 C 語言中的 goto 標(biāo)號(hào)很類似?都是表示一個(gè)地址。

注意這里賦值給棧頂指針 SP 寄存器的值是 20H。

因?yàn)?span>棧段的使用是從高地址向低地址方向進(jìn)行的,所以需要把棧頂指針設(shè)置為最大地址單元的下一個(gè)地址空間。

Linux從頭學(xué)03:如何告訴 CPU,代碼段、數(shù)據(jù)段、棧段在內(nèi)存中什么位置?
假設(shè)把第一個(gè)數(shù)據(jù)入棧時(shí)(eg: 先執(zhí)行 mov ax, 1234h,再執(zhí)行 push ax),CPU 要做的事情是: 先執(zhí)行 SP = SP - 2,此時(shí) SS:SP 指向 1000:001E,然后再把 1234h 存儲(chǔ)到這個(gè)地址空間:

Linux從頭學(xué)03:如何告訴 CPU,代碼段、數(shù)據(jù)段、棧段在內(nèi)存中什么位置?
另外,代碼中最后一句 end start,用來告訴編譯器:代碼段中 start 標(biāo)號(hào)代表的地址,就是這個(gè)程序的入口地址,編譯之后這個(gè)入口地址信息也會(huì)被寫入可執(zhí)行程序中。

當(dāng)可執(zhí)行文件被加載到內(nèi)存中之后,加載程序會(huì)找到這個(gè)入口地址,然后把 CS:IP 設(shè)置為指向這個(gè)入口地址,從而開始執(zhí)行第一條指令。

我們?cè)賮韺?duì)比一下《Linux系統(tǒng)中編譯、鏈接的基石-ELF文件:扒開它的層層外衣,從字節(jié)碼的粒度來探索》中列出的 ELF 可執(zhí)行文件中的入口地址,它與上面 8086 下的 start 標(biāo)號(hào)代表的入口地址,在本質(zhì)上都是一樣的道理:

Linux從頭學(xué)03:如何告訴 CPU,代碼段、數(shù)據(jù)段、棧段在內(nèi)存中什么位置?

------ End ------

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱"軟通動(dòng)力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉