01-初始化載入程式

卡卡发發表於2024-07-19

原理說明



Bios會載入第一扇區到記憶體中,只有512位元組,因此該部分的程式無法做太多的事,因此需要擴充套件程式,有以下兩種方式:

這裡選用方式二,因為實現起來相對簡單一點。



16位真實模式的情況下,暫存器也是16位,詳見下圖右邊的AX BX CX DX

  • 8086CPU的定址範圍是1MB

  • 確定實體地址的方法:
    CPU 訪問記憶體單元時要給出記憶體單元的地址。
    所有記憶體單元構成的儲存空間是一個一維的線性空間。
    每一個記憶體單元都有唯一的地址,叫實體地址。
    8086 有 20 位地址匯流排,可傳送 20 位地址,定址能力是 2^20 = 1 MB
    8086 是 16 位結構的 CPU,運算器一次最多處理 16 位的資料,暫存器的最大寬度為 16 位。
    在 8086 cpu內部處理的、傳輸、暫存的地址也是 16 位,定址能力只有 64 KB

  • 如何處理地址匯流排 20 位的定址能力受限於 16 位地址長度這一問題?
    用兩個 16 位地址(段地址和偏移地址)合成一個 20 位的實體地址。
    地址加法器合成實體地址的方法: 實體地址 = 段地址 ∗ 16 + 偏移地址

  • 記憶體的分段表示法:
    記憶體並沒有分段,段的劃分來自於CPU


參考連結 :https://blog.csdn.net/AlwaysBeShine/article/details/137412067

實操


初始的start.h如下:


(1)先將暫存器的值置為0

(這裡使用AT&T格式的彙編指令,另一種格式是intel格式)


編譯後檢視反編譯檔案,可以看到第一個扇區的最後兩個位元組的值,55和aa,說明第一個扇區中確實有引導程式碼,因此可以把第一扇區中的內容載入到記憶體中


(2)接著連線qemu除錯一下


  • 按F5

  • 終端 執行任務 除錯準備 繼續而不掃描任務輸出

  • 接著檢視暫存器的值

  • 按F11可以進行單步操作,觀察暫存器的值的變化

透過觀察esp暫存器發現,esp暫存器的值不是0x7c00,經過檢查發現是賦值的語句漏寫了一個$,如下所示:

重新編譯後除錯,esp的值就正確了




相關文章