原理說明
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的值就正確了