學(xué)習(xí)筆記
使用教材(配書源碼以及使用方法)
《一個(gè)64位操作系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)》
http://www.ituring.com.cn/book/2450
http://www.reibang.com/p/28f9713a9171
參考資料
Setting segment registers after ORG instruction
https://stackoverflow.com/questions/54045259/setting-segment-registers-after-org-instruction
如果你的代碼中有一個(gè)標(biāo)號(hào)叫做bootmsg,它的值是
samll offset
:
- 在
org 0
的時(shí)候吏廉,這個(gè)標(biāo)號(hào)的值被解讀成0x0000+samll offset
啰脚;- 在
org 0x7c00
時(shí),這個(gè)標(biāo)號(hào)的值被解讀成0x7c00+samll offset
- 這個(gè)
samll offset
其實(shí)就是標(biāo)號(hào)所在處距離代碼開始處的代碼字節(jié)數(shù)
org 到底影響了誰谱轨?
- 第一,
org
指令影響的是 標(biāo)號(hào)的絕對(duì)地址 - 第二吠谢,
org
指令不會(huì)影響寄存器土童,說白了,不會(huì)影響CS 工坊、DS献汗、ES、SS
為什么org
后面要加個(gè)0x7c00
王污?
- 這個(gè)問題的本質(zhì)是問為什么值是
0x7c00
罢吃,不是0x0000
,或者0x1234
昭齐,也不是0xABCD
阮一峰:為什么主引導(dǎo)記錄的內(nèi)存地址是0x7C00尿招?
http://www.ruanyifeng.com/blog/2015/09/0x7c00.html
容易混淆的概念
首先,無論你的匯編代碼頭部加不加一句
org 0x ★♂☆◆
指令,你的主引導(dǎo)扇區(qū)代碼都會(huì)被BIOS 自動(dòng)加載到內(nèi)存的0x0000:7C00
處就谜,自動(dòng)加載這是焊死在硬件上面的規(guī)范怪蔑,說白了,自動(dòng)加載與org
指令半點(diǎn)關(guān)系都沒有丧荐;其次缆瓣,是不是主引導(dǎo)扇區(qū)代碼,看的是你扇區(qū)最后兩個(gè)字節(jié)是不是
0x55aa
篮奄,也和org
指令沒有半點(diǎn)關(guān)系捆愁;然后割去,有些主引導(dǎo)扇區(qū)匯編代碼不加org指令也可以正常運(yùn)行窟却,就是因?yàn)槟切┐a里面沒有涉及到 標(biāo)號(hào)label 相關(guān)的代碼,不需要對(duì) 標(biāo)號(hào)label 進(jìn)行絕對(duì)地址的計(jì)算
[舉例]下面這就是沒有使用label也沒有使用org指令的主引導(dǎo)扇區(qū)代碼
http://www.reibang.com/p/207aaf0f986b
接著呻逆,標(biāo)號(hào)是標(biāo)號(hào)夸赫,標(biāo)號(hào)不是寄存器,標(biāo)號(hào)是程序員可以自由任意隨便取名字的咖城,取的那個(gè)名字只是幫助你閱讀代碼用的茬腿,在代碼經(jīng)過匯編編譯器之后標(biāo)號(hào)會(huì)被解讀成一個(gè)具體的數(shù)值,
org
影響的就是最后算標(biāo)號(hào)的那個(gè)具體數(shù)值宜雀;最后切平,這個(gè)標(biāo)號(hào)代碼的那個(gè)具體的數(shù)值是什么?
是一個(gè)offset
辐董,即當(dāng)前標(biāo)號(hào)所在代碼行距離代碼開始處的字節(jié)數(shù)
為什么需要 org 指令悴品?
假設(shè),你的標(biāo)號(hào)距離你的代碼開始處是
八個(gè)字節(jié)
简烘,那個(gè)標(biāo)號(hào)的值原本應(yīng)該就是0x08
的苔严,這個(gè)原本可以是不寫org指令
,也可以是寫個(gè)org 0x0000
孤澎,反正無論哪種這時(shí)標(biāo)號(hào)會(huì)被解讀成數(shù)值0x00000008
届氢;由于你是主引導(dǎo)扇區(qū)的代碼,你的代碼被自動(dòng)加載到內(nèi)存
0x0000:7C00
處了覆旭,代碼被加載到內(nèi)存退子,實(shí)際上是說機(jī)器碼被加載到內(nèi)存,也就說是說無論你的代碼被加載到0x0000:7C00
還是被加載到0x1234:5678
這里型将, 數(shù)值0x00000008
還是數(shù)值0x00000008
絮供;那么問題就來了?
數(shù)值0x00000008
是一個(gè)絕對(duì)地址茶敏,你現(xiàn)在代碼全部在0x0000:7C00
壤靶,你真正想要找的標(biāo)號(hào)是被放到了從0x0000:7C00
開始后的八個(gè)字節(jié)的地方,它應(yīng)該是0x00007C000+0x00000008 = 0x00007C08
而不是0x00000008
那么如何解決惊搏?
[1] 要么直接修改標(biāo)號(hào)的絕對(duì)地址贮乳,在使用標(biāo)號(hào)賦值的時(shí)候忧换,
強(qiáng)制加上0x7c00
,比如mov ax,bootmsg
寫成mov ax,bootmsg+0x7C00
向拆;
[2] 要么亚茬,在代碼開頭使用org 0x7C00
,代碼還是寫mov ax ,bootmsg
但是它會(huì)悄悄地把bootmsg解讀成bootmsg+0x7C00
如何驗(yàn)證猜想
- [OS64位][004]調(diào)試源碼:使用工具 nasm 浓恳、bochs 驗(yàn)證 org 0x7c00 對(duì)標(biāo)號(hào)StartBootMessage 最終數(shù)值的影響