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时,将它注释掉就可

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