2022-02-16 Linux 0.11源碼筆記(一)基址的賦值

跑起了一個(gè)hello world的操作系統(tǒng) ,流程可以看2022-02-10 嘗試跑個(gè)hello world的操作系統(tǒng)。接下來要做的事情還有很多,怎么讓操作系統(tǒng)干事情?比如,最簡單的,時(shí)間怎么顯示?文件怎么創(chuàng)建?網(wǎng)絡(luò)怎么請求?UI怎么繪制?APP怎么安裝上去?等等一系列的問題,都需要去解決。那么,這些問題要怎么解決呢?我想到的方案的是看源碼,看看別人是怎么做的,才好知道自己應(yīng)該怎么做。于是,我找到了一份Linux 最簡單的源碼,0.11版本,Linux 0.11源碼。下面是看源碼做的一些筆記。
首先看看目錄結(jié)構(gòu),文件目錄不多。

├── Makefile
├── README.md
├── boot
├── cscope.files
├── fs
├── include
├── init
├── kernel
├── lib
├── mm
└── tools

boot則是啟動目錄,也就是最先執(zhí)行的代碼,所以我們先看看boot里面的。一共三個(gè)文件,其中第一個(gè)bootsect.s是啟動相關(guān)的,后面兩個(gè)后面再說

.
├── bootsect.s
├── head.s
└── setup.s

我們來打開bootsect.s文件看看里面的代碼。先看最開始的一部分

.globl begtext, begdata, begbss, endtext, enddata, endbss
.text
begtext:
.data
begdata:
.bss
begbss:
.text

SETUPLEN = 4                ! nr of setup-sectors
BOOTSEG  = 0x07c0           ! original address of boot-sector
INITSEG  = 0x9000           ! we move boot here - out of the way
SETUPSEG = 0x9020           ! setup starts here
SYSSEG   = 0x1000           ! system loaded at 0x10000 (65536).
ENDSEG   = SYSSEG + SYSSIZE     ! where to stop loading

這部分代碼很容易理解,都是一些變量的定義,其中需要關(guān)注的是BOOTSEG = 0x07c0,看注釋可以知道0x07c0是啟動的首地址,也就是說,機(jī)器開機(jī)通電后,經(jīng)過一系列的自檢操作,bios啟動等等后,最后會跳到這個(gè)地址上,開始執(zhí)行操作系統(tǒng)的代碼。至于為什么是這個(gè)地址?可以不深究(因?yàn)槲乙矝]去深究,感興趣的可以去查一下然后評論告訴我)。
繼續(xù)往下走。今天我們先看兩行代碼

_start:
    mov ax,#BOOTSEG  !#BOOTSEG就是上面定義的0x07c0
    mov ds,ax

第一行代碼就是把0x07c0賦值給ax
第二行代碼就是把a(bǔ)x賦值給ds
最后的結(jié)果是,ax和ds里面的值都是0x07c0。那么這樣做的作用是什么呢?這個(gè)要從ds的作用說起了,ds一般作為缺省的基址,何為基址?這么說吧,基址+偏移地址 = 物理地址,這里還有一個(gè)小細(xì)節(jié),ds會先左移4位再和偏移地址相加。也就是說,實(shí)際上基址是0x7c00,不過ds的值依然是0x07c0。只是在計(jì)算的時(shí)候會執(zhí)行左移的操作。所以,回到剛開始的問題 ,這兩句代碼的作用 ,其實(shí)就是保存一個(gè)基址。而保存基址的作用就是,開機(jī)時(shí)BIOS會執(zhí)行到這個(gè)地址,只有把代碼寫在這個(gè)地址上,才會被執(zhí)行到。

問題:為什么不直接把0x07c0賦值給ds呢?而要ax來中轉(zhuǎn)一下?
答:據(jù)說是不允許直接給ds賦值,匯編也有它的要求,其中三條是

  • 不能直接給內(nèi)存地址賦值,必須通過DS:[偏移地址]指向內(nèi)存。
  • 不能直接通過給DS賦值,必須通過寄存器中轉(zhuǎn)。
  • 不能修改CS、IP的值

這里擴(kuò)展一些知識


寄存器結(jié)構(gòu).png

AX:寄存器稱為累加器,常用于存放算術(shù)、邏輯運(yùn)算中的操作數(shù)或結(jié)果。另外,所有的I/O指令都要使用累加器與外設(shè)接口傳遞數(shù)據(jù)。
BX:寄存器稱為基址寄存器,常用來存放訪問內(nèi)存時(shí)的地址。
CX:寄存器稱為計(jì)數(shù)寄存器,在循環(huán)、串操作指令中用作計(jì)數(shù)器。
DX:寄存器稱為數(shù)據(jù)寄存器,在寄存器間接尋址中的I/O指令中存放I/O端口的地址。
CS:代碼段。
DS:數(shù)據(jù)段寄存器,一般用于存放數(shù)據(jù)。也是缺省的基址
SS:堆棧段。
ES:附加段。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容