設(shè)置
  • 日夜間
    隨系統(tǒng)
    淺色
    深色
  • 主題色

Linux 0.11 第 3 回 | 做好訪問(wèn)內(nèi)存的最基礎(chǔ)準(zhǔn)備工作

低并發(fā)編程 2022/10/1 14:51:30 責(zé)編:子非

本文來(lái)自微信公眾號(hào):低并發(fā)編程 (ID:dibingfa),作者:閃客

本系列會(huì)以一個(gè)讀小說(shuō)的心態(tài),從開(kāi)機(jī)啟動(dòng)后的代碼執(zhí)行順序,帶著大家閱讀和賞析 Linux 0.11 全部核心代碼,了解操作系統(tǒng)的技術(shù)細(xì)節(jié)和設(shè)計(jì)思想。

你會(huì)跟著我一起,看著一個(gè)操作系統(tǒng)從啥都沒(méi)有開(kāi)始,一步一步最終實(shí)現(xiàn)它復(fù)雜又精巧的設(shè)計(jì),讀完這個(gè)系列后希望你能發(fā)出感嘆,原來(lái)操作系統(tǒng)源碼就是這破玩意。以下是已發(fā)布文章的列表,詳細(xì)了解本系列可以先從開(kāi)篇詞看起。

開(kāi)篇詞

第一回 最開(kāi)始的兩行代碼

第二回 自己給自己挪個(gè)地兒

本系列的 GitHub 地址:點(diǎn)此訪問(wèn)

------- 正文開(kāi)始 -------

書(shū)接上回,上回書(shū)咱們說(shuō)到,操作系統(tǒng)的代碼最開(kāi)頭的 512 字節(jié)的數(shù)據(jù),從硬盤(pán)的啟動(dòng)區(qū)先是被移動(dòng)到了內(nèi)存 0x7c00 處,然后又立刻被移動(dòng)到 0x90000 處,并且跳轉(zhuǎn)到此處往后再稍稍偏移 go 這個(gè)標(biāo)簽所代表的偏移地址處。

那我們接下來(lái),就繼續(xù)把我們的目光放在 go 這個(gè)標(biāo)簽的位置,跟著 CPU 的步伐往后看。

: mov ax,cs
    mov ds,ax
    mov es,ax
    mov ss,ax
    mov sp,#0xFF00

全都是 mov 操作,那好辦了。

這段代碼的直接意思很容易理解,就是把 cs 寄存器的值分別復(fù)制給 ds、es ss 寄存器,然后又把 0xFF00 給了 sp 寄存器。

回顧下 CPU 寄存器圖。

cs 寄存器表示代碼段寄存器,CPU 當(dāng)前正在執(zhí)行的代碼在內(nèi)存中的位置,就是由 cs:ip 這組寄存器配合指向的,其中 cs 是基址,ip 是偏移地址。

由于之前執(zhí)行過(guò)一個(gè)段間跳轉(zhuǎn)指令,還記得不?

jmpi go,0x9000

所以現(xiàn)在 cs 寄存器里的值就是 0x9000,ip 寄存器里的值是 go 這個(gè)標(biāo)簽的偏移地址。那這三個(gè) mov 指令就分別給 ds、es 和 ss 寄存器賦值為了 0x9000。

ds 為數(shù)據(jù)段寄存器,之前我們說(shuō)過(guò)了,當(dāng)時(shí)它被復(fù)制為 0x07c0,是因?yàn)橹暗拇a在 0x7c00 處,現(xiàn)在代碼已經(jīng)被挪到了 0x90000 處,所以現(xiàn)在自然又改賦值為 0x9000 了。

es 是擴(kuò)展段寄存器,僅僅是個(gè)擴(kuò)展,不是主角,先不用理它。

ss 為棧段寄存器,后面要配合?;芳拇嫫?sp 來(lái)表示此時(shí)的棧頂?shù)刂?。而此時(shí) sp 寄存器被賦值為了 0xFF00 了,所以目前的棧頂?shù)刂肪褪?ss:sp 所指向的地址 0x9FF00 處。

其實(shí)到這里,操作系統(tǒng)的一些最最最最基礎(chǔ)的準(zhǔn)備工作,就做好了。都做了些啥事呢?

第一,代碼從硬盤(pán)移到內(nèi)存,又從內(nèi)存挪了個(gè)地方,放在了 0x90000 處。

第二,數(shù)據(jù)段寄存器 ds代碼段寄存器 cs 此時(shí)都被設(shè)置為了 0x9000,也就為跳轉(zhuǎn)代碼和訪問(wèn)內(nèi)存數(shù)據(jù),奠定了同一個(gè)內(nèi)存的基址地址,方便了跳轉(zhuǎn)和內(nèi)存訪問(wèn),因?yàn)閮H僅需要指定偏移地址即可了。

第三,棧頂?shù)刂繁辉O(shè)置為了 0x9FF00,具體表現(xiàn)為棧段寄存器 ss 為 0x9000,?;芳拇嫫?sp 為 0xFF00。棧是向下發(fā)展的,這個(gè)棧頂?shù)刂?0x9FF00 要遠(yuǎn)遠(yuǎn)大于此時(shí)代碼所在的位置 0x90000,所以棧向下發(fā)展就很難撞見(jiàn)代碼所在的位置,也就比較安全。這也是為什么給棧頂?shù)刂吩O(shè)置為這個(gè)值的原因,其實(shí)只需要離代碼的位置遠(yuǎn)遠(yuǎn)的即可。

做好這些基礎(chǔ)工作后,接下來(lái)就又該折騰了其他事了。

總結(jié)拔高一下,這一部分其實(shí)就是把代碼段寄存器 cs,數(shù)據(jù)段寄存器 ds棧段寄存器 ss?;芳拇嫫?sp 分別設(shè)置好了值,方便后續(xù)使用。

再拔高一下,其實(shí)操作系統(tǒng)在做的事情,就是給如何訪問(wèn)代碼,如何訪問(wèn)數(shù)據(jù),如何訪問(wèn)棧進(jìn)行了一下內(nèi)存的初步規(guī)劃。其中訪問(wèn)代碼和訪問(wèn)數(shù)據(jù)的規(guī)劃方式就是設(shè)置了一個(gè)基址而已,訪問(wèn)棧就是把棧頂指針指向了一個(gè)遠(yuǎn)離代碼位置的地方而已。

所以,千萬(wàn)別多想,就這么點(diǎn)事兒。那再給大家留個(gè)作業(yè),把當(dāng)前的內(nèi)存布局畫(huà)出來(lái),告訴我現(xiàn)在 cs、ip、ds、ss、sp 這些寄存器的值,在內(nèi)存布局中的位置。

好了,接下來(lái)我們應(yīng)該干什么呢?我們回憶下,我們目前僅僅把硬盤(pán)中 512 字節(jié)加載到內(nèi)存中了,但操作系統(tǒng)還有很多代碼仍然在硬盤(pán)里,不能拋下他們不管呀。

所以你猜下一步要干嘛了?

后面的世界越來(lái)越精彩,欲知后事如何,且聽(tīng)下回分解。

廣告聲明:文內(nèi)含有的對(duì)外跳轉(zhuǎn)鏈接(包括不限于超鏈接、二維碼、口令等形式),用于傳遞更多信息,節(jié)省甄選時(shí)間,結(jié)果僅供參考,IT之家所有文章均包含本聲明。

相關(guān)文章

關(guān)鍵詞:Linuxlinux

軟媒旗下網(wǎng)站: IT之家 最會(huì)買(mǎi) - 返利返現(xiàn)優(yōu)惠券 iPhone之家 Win7之家 Win10之家 Win11之家

軟媒旗下軟件: 軟媒手機(jī)APP應(yīng)用 魔方 最會(huì)買(mǎi) 要知