1馬上dong hand write one 罪曉的OS

1.1準備工作

  • 硬件
    • 計算機Windows
    • 一張空白軟盤
  • 軟件
    • 彙編編譯器NASM。最新版此鏈接http://sourceforge.net/projects/nasm
    • (爲啥NASM,而不MASM或TASM?這一點後面有解釋。)
  • 軟盤絕對扇區讀寫工具
    • 如本書附贈光盤中的FloppyWriter.exe
      • Floppy Disk是PC中最早用的可移介質。
      • 軟盤的讀寫通過軟盤驅動器完成
      • 軟盤驅動器設計能接收可移動式軟盤,
      • 常用:容量爲1.44MB的3.5英寸

1.2 10分鐘完成的OS

  • 一個“OS”只有20行

在這裏插入圖片描述

  org 07c00h    ;高速編譯器程序加載到7c00處
  mov ax, cs
  mov ds, ax    
  mov es, ax    
  call DispStr  ;調用顯示字符串例程
  jmp $         ;無線循環
DispStr:
  mov ax, BootMessage
  mov bp, ax
  mov cx, 16
  mov ax, 01301h; ah=13,a1 = 01h
  mov bx, 000ch ; 頁號爲0(bh = 0) 黑底紅字 (b1 = 0Ch,高亮)
  mov dl, 0
  int 10h       ; 10h號中斷
  ret
BootMessage:  db  "Hello, OS world!"
times 510-($-$$) db 0;填充剩下的空間。使生成的二進制代碼恰好爲512字節

dw 0xaa55 ;結束標誌

我估計第一個7c00,第二個是7c02…

  • 用NASM編譯下
  • nasm boot.asm -o boot.bin

  • 得到一個512B的boot.bin
  • 用軟盤絕對扇區讀寫工具將這個文件寫到空白軟盤的第一個扇區
  • 第一個OS已完成
  • 這張軟盤已是一張引導盤

  • 把它放到你的軟驅中重新啓動計算機,從軟盤引導,你看到了什麼?

  • 計算機顯示出紅色的“ Hello, OS world!”,你的“操作系統”在運行
    在這裏插入圖片描述

  • 如果用 Virtual PC的話(下文中將會有關於 Virtual PC的詳細介紹),你應該能看到圖1-1

  • 你已經制作了一個可以引導的軟盤了!

1.3 Boot Sector

  • 你剛剛所完成的並不是一個完整的OS,
    • 僅是一個最最簡單的引導扇區( Boot Sector)。
  • 它是直接在裸機上運行的,不依賴於任何其他軟件,
  • 這和我們平時所編寫的應用軟件有本質區別。
  • 它不是操作系統,但已經具備了操作系統的一個特性

  • 計算機電源打開時,它會先加電自檢(POST),然後尋找啓動盤
  • 如果是選擇從軟盤啓動,
    • 計算機就檢査軟盤的0面0磁道1扇區
    • 如果發現它以0xAA55(把此扇區看做字符數組sector,相當於sector[510]=0x55,且 sector[511]=0xAA)結束,則BIOS認爲它是一個引導扇區,也就是Boot Sector。
  • 一個正確的Boot Sector除了以OxAA55結束外,
    • 還應包含一段少於512B的執行碼

  • 一且BIOS發現了Boot Sector,就會將這512B的內容裝載到內存的0000:7c00處,然後跳到0000:7c00處將控制權徹底交給這段引導代碼
  • 到此計算機不再由BIOS中固有的程序來控制,
    • 而變成由操作系統的一部分來控制

  • 第一行會出現org 07c00
  • 這行代碼就是告訴編譯器,
  • 這段程序要被加載到內存偏移地址7c00處

1.4代碼解釋

  • 主體框架只有5行(從第2行到第6行),調用了一個顯示字符串的子程序。
  • 2、3、4行是3個mov指令,使ds和es兩個段寄存器指向與cs相同的段,以便在以後數據操作時能定位到正確的位置。
  • 第5行調用子程序顯示字符串,然後jmp $讓程序無限循環

  • NASM中,

  • 不被方括號括起來的標籤或變量名都被認爲是地址,

  • 訪問標籤中的內容必須使用[]。

  • mov ax, Bootmessage

  • 把“ Hello, OS world!”這個字符串的首地址傳給ax。

  • 如果有:
    foo dw 1

  • mov ax,foo將把foo的地址傳給ax,

  • mov bx,[foo]將把bx的值賦爲1。

  • NASM中,變量和標籤是一樣的

    • foo dw 1\equivfoo: dw 1

  • Offset這個關鍵字在NASM也是不需要的。
    • 不加方括號時表示的就是 Offset
    • 這是NASM的一大優點,要地址就不加方括號,也不必額外地用什麼 Offset
    • 想要訪問地址中的內容就必須加方括號。

  • $表示當前行被彙編後的地址。
  • 把剛剛生成的二進制代碼文件反彙編

在這裏插入圖片描述

  • 打開 disboot.asm,
  • 發現
    00007C09 EBFE jmp short 0x7c09
  • $原來就是0x7c09

  • $$表示
  • 一個(secton)的開始處被彙編後的地址。
  • 我們的程序只有1個節,所以,實際上就表示程序被編譯後的開始地址,也就是0x7c00。

在這裏插入圖片描述

  • $-$$表示本行距離程序開始處的相對距離。
  • times 510-($-$$) db 0表示將0這個字節重複遍
  • 也就是在剩下的空間中不停地填充0,直到程序有510B

1.5水畫下的冰山

  • Boot Sector爲例,想一個辦法,讓它調試起來容易
  • 只要把一行改成“org 0100h”就可編譯成一個.COM讓它在DOS下運行
  • nasm boot.asm -o boot.com
  • 一個易於執行和調試的Boot Sector就製作完畢
  • 調試COM文件可能讓你彷彿一下子回到20世紀

  • Turbo Debugger是不錯的調試工具,“圖形化”界面,全屏操作,用起來感覺和一個“嚴重”精簡後的 Windows差不多

  • NASM給我們提供了預編譯宏,
  • 把原來的“org 07c00h”一行變成許多行

在這裏插入圖片描述

  • 如果想要調試,就讓第一行有效,想要做 Boot Sector時,將它註釋掉就可

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章