从计算机结构到汇编程序入门
很早就想看看这本书。但书中有很多配套的资料和软件过于久远。还是一个以FAT16格式,安装在软盘中的操作系统。一些验证操作无法实现,想解决这些问题的同时记录下自己的学习笔记。
本书采用windows编程环境,配套的相关软件作者在随书配套的光盘中均有提供。实测windows10可直接运行。
原作者官网http://hrb.osask.jp/
这本书牵扯到计算机组成原理、操作系统、数据结构、汇编语言、C语言等知识,没有一定的计算机基础的话看起来会很吃力,完全不适合小白。
第一天的内容总结起来就是用三种方法写一个helloos.img——一个能在开机界面显示hello,world的img文件。
- 一:直接使用二进制机器码
- 二:用汇编语言直接写入二进制机器码
- 三:用标准汇编语言编写二进制代码
相关工具及下载
其中需要用到二进制文件编辑器和汇编语言的编译器。
这里推荐hexed.it和光盘中配套的NASM软件
hexed.it有在线版的web和windows应用商店版
在线版地址:https://hexed.it/
windows下载链接:https://apps.microsoft.com/detail/9pgqh18bwdsf?launch=true&mode=full&hl=zh-cn&gl=cn&ocid=bingwebsearch
NASM直接用光盘中给的就行,原作者还优化过。此处给出完整的光盘压缩包。
光盘介绍:
光盘中有三个目录omake、projects、tolset
- omake:因为光盘容量还有很多,于是作者赛了一些别的源代码,详情可参阅omake\omake.txt
- projects:每天的代码
- tolset:以后每天都要用的工作目录
原始光盘中源码文件的注释均为日语,编码设置不到位会导致严重的乱码,但不影响代码本身。
接下来就开始编程了
注:目录就是文件夹,一般linux系统中习惯称之为目录,windows中习惯称之为文件夹。
编写机器码
源码位置:\30天自制操作系统\projects\01_day\helloos0\helloos.img
拖入hexed.it可直接打开。
首先介绍下hexed.it编辑界面的格式。
左侧为地址栏,地址为16进制。
中间为16进制机器码。
右侧为同地址的ASCII码表示。
在地址0——82之间输入以下内容
;复制代码时不要把地址复制进去了。
00000000 EB 4E 90 48:45 4C 4C 4F|49 50 4C 00:02 01 01 00
00000010 02 E0 00 40:0B F0 09 00|12 00 02 00:00 00 00 00
00000020 40 0B 00 00:00 00 29 FF|FF FF FF 48:45 4C 4C 4F
00000030 2D 4F 53 20:20 20 46 41|54 31 32 20:20 20 00 00
00000040 00 00 00 00:00 00 00 00|00 00 00 00:00 00 00 00
00000050 B8 00 00 8E:D0 BC 00 7C|8E D8 8E C0:BE 74 7C 8A
00000060 04 83 C6 01:3C 00 74 09|B4 0E BB 0F:00 CD 10 EB
00000070 EE F4 EB FD:0A 0A 68 65|6C 6C 6F 2C:20 77 6F 72
00000080 6C 64 0A 00:00 00 00 00|00 00 00 00:00 00 00 00
在地址1FE——202之间编写以下内容。
000001F0 00 00 00 00:00 00 00 00|00 00 00 00:00 00 55 AA
00000200 F0 FF FF 00:00 00 00 00|00 00 00 00:00 00 00 00
之后一直到168000全是0。编辑器中可用Ctrl+C/V复制粘贴。
这个编译器不会自动取消框选的代码,需要手动取消,如果选的太多记得右键”取消全选“
复制时样式选择”Plain Data”,数制”十六进”制或”二进制”都可以。
粘贴时选择”作为16进制数值“。
完成后保存为helloos.img文件,今天的主要目标便完成了。
模拟运行
在光盘的tolset目录中新建一个新目录,名称随意,把helloos.img文件复制进去,路径类似于这样
F:\30天自制操作系统\tolset\新建文件夹\helloos.img
同目录中新建记事本文件写入以下内容
copy helloos.img ..\z_tools\qemu\fdimage0.bin
..\z_tools\make.exe -C ../z_tools/qemu
保存为run.bat
之后双击运行run.bat
即可进行模拟运行,会显示hello,world画面
查看右侧的ASCII码就能明白,源码中地址0x00000076——0x00000081就是hello,world
因此后面可根据ASCII自己添加想添加的内容
运行结果
汇编直接写入
源码文件:\30天自制操作系统\projects\01_day\helloos1\helloos.nas
拖入记事本可直接打开。
这个没什么好说的,就是用汇编语言的方法把第一种方法的机器码再抄一遍。
打开记事本,写入以下内容,保存为helloos.nas文件
DB 0xeb, 0x4e, 0x90, 0x48, 0x45, 0x4c, 0x4c, 0x4f
DB 0x49, 0x50, 0x4c, 0x00, 0x02, 0x01, 0x01, 0x00
DB 0x02, 0xe0, 0x00, 0x40, 0x0b, 0xf0, 0x09, 0x00
DB 0x12, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00
DB 0x40, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x29, 0xff
DB 0xff, 0xff, 0xff, 0x48, 0x45, 0x4c, 0x4c, 0x4f
DB 0x2d, 0x4f, 0x53, 0x20, 0x20, 0x20, 0x46, 0x41
DB 0x54, 0x31, 0x32, 0x20, 0x20, 0x20, 0x00, 0x00
RESB 16
DB 0xb8, 0x00, 0x00, 0x8e, 0xd0, 0xbc, 0x00, 0x7c
DB 0x8e, 0xd8, 0x8e, 0xc0, 0xbe, 0x74, 0x7c, 0x8a
DB 0x04, 0x83, 0xc6, 0x01, 0x3c, 0x00, 0x74, 0x09
DB 0xb4, 0x0e, 0xbb, 0x0f, 0x00, 0xcd, 0x10, 0xeb
DB 0xee, 0xf4, 0xeb, 0xfd, 0x0a, 0x0a, 0x68, 0x65
DB 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x77, 0x6f, 0x72
DB 0x6c, 0x64, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00
RESB 368
DB 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa
DB 0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
RESB 4600
DB 0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
RESB 1469432
- DB:直接向文件中写入1个字节(8bit)
- RESB:后接数字(十进制)简单地说就是接着上面的代码后面多少字节填0
把文件保存到:\30天自制操作系统\tolset\helloos1目录中
注:helloos1目录名称无要求,可随便取。为了以后方便采用和原作者相同的命名。
helloos1目录中新建记事本,写入以下内容,保存为asm.bat
..\z_tools\nask.exe helloos.nas helloos.img
双击运行asm.bat,helloos.nas文件便编译为helloos.img。
同样新建run.bat
copy helloos.img ..\z_tools\qemu\fdimage0.bin
..\z_tools\make.exe -C ../z_tools/qemu
也可模拟运行。
标准汇编编写
源码文件:\30天自制操作系统\projects\01_day\helloos2\helloos.nas
接下来正式进入编写环节了
直接把 \30天自制操作系统\projects\01_day\helloos2目录复制到 \30天自制操作系统\tolset目录中
源码:
; hello-os
; TAB=4
; 以下代码为启动区
; 以下段落为标准FAT12格式软盘专用代码
DB 0xeb, 0x4e, 0x90 ;启动区开头
DB "HELLOIPL" ; 启动区名称,可取任意字符串(8字节)
DW 512 ; 每个扇区的大小(必须为512字节)
DB 1 ; 簇大小,(必需为1个扇区)
DW 1 ; FAT的起始位置(一般是从第一个扇区开始)
DB 2 ; FAT的个数(必须为2)
DW 224 ; 根目录大小,(一般设置为224项)
DW 2880 ; 该硬盘大小(必须为2880扇区)
DB 0xf0 ; 硬盘种类(必须是0xf0)
DW 9 ; FAT长度(必须是9个扇区)
DW 18 ; 1个磁道有几个扇区(必须是18个)
DW 2 ; 磁头数(必须是2个)
DD 0 ; 不使用分区,此处为0
DD 2880 ; 重写一次,硬盘大小
DB 0,0,0x29 ; 不知道是干什么的,但必要写
DD 0xffffffff ; 可能是卷标号码
DB "HELLO-OS " ; 硬盘名称(11字节)
DB "FAT12 " ; 硬盘文件系统名称(8字节)
RESB 18 ; 空出18字节
; 程序主体
DB 0xb8, 0x00, 0x00, 0x8e, 0xd0, 0xbc, 0x00, 0x7c
DB 0x8e, 0xd8, 0x8e, 0xc0, 0xbe, 0x74, 0x7c, 0x8a
DB 0x04, 0x83, 0xc6, 0x01, 0x3c, 0x00, 0x74, 0x09
DB 0xb4, 0x0e, 0xbb, 0x0f, 0x00, 0xcd, 0x10, 0xeb
DB 0xee, 0xf4, 0xeb, 0xfd
; 信息显示部分
DB 0x0a, 0x0a ; 2个换行
DB "hello, world"
DB 0x0a ; 换行
DB 0
RESB 0x1fe-$ ; 当前到0x1fe地址的位置全部填0
DB 0x55, 0xaa ; 启动区末尾标识,必须是0x55, 0xaa
; 启动区结束
; 以下是程序以外的输出部分
DB 0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
RESB 4600
DB 0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
RESB 1469432
- DW:直接向文件中写入2个字节(16bit)
- DD:直接向文件中写入4个字节(32bit)
- RESB 0x1fe-$ :$在此处为当前代码的字节数,此时的代码为132字节
同样运行asm.bat,helloos.nas编译成helloos.img文件
运行run.bat文件便可模拟运行。
另外,要是细扣机器码和汇编代码时会发现
DW 512 ; 每个扇区的大小(必须为512字节)
这行汇编在机器码中被编译成了00 02,而512的16进制表示为0200。这是因为计算机中采用小端方式存储。后面的 DW 224 ; 根目录大小,(一般设置为224项)
。。。。。。同理。
实际运行
注意:此操作系统没有关机程序,只能强行关机
其实这个helloos.img文件是能在物理机中运行的,用rufus软件把helloos.img写入U盘中
注:写入时会格式化整个U盘
之后用DiskGenius打开,可看到U盘有个1.4MB的分区。用16进制编辑打开这一分区可看到之前写入的文件
之后用U盘插入电脑,重新启动,进入BIOS,选择U盘作为启动项(注意BIOS改为传统BIOS+MBR模式,关闭安全启动等。。。)
虚拟机运行
img文件没法直接安装,需要用各种转换工具变为虚拟机支持的格式,不同虚拟机支持的文件格式还不一样,太麻烦。直接用上一节制作好的U盘启动即可。
注意:此操作系统没有关机程序,只能强行关机
VMware Workstation
插上制作好的U盘然后新建虚拟机,高级模式,此处只把必要的修改进行说明
操作系统选择MS-DOS
处理器1核,内存16MB即可,不使用网络
使用物理磁盘
设备这里选择你的U盘编号
怎么查看磁盘编号?
打开磁盘管理,图中左侧的磁盘 x即是磁盘编号。
图中U盘为磁盘5故,这里选择磁盘5,同时选择使用整个磁盘。
设置完成,启动虚拟机
Hyper-V
打开磁盘管理
把U盘脱机
注意:U盘在windows有两种识别模式,一种是正经的U盘,另一种会识别为移动硬盘。此操作只有识别为移动硬盘的U盘才能进行。
Hyper-V中新建虚拟机
选择第一代虚拟机,内存32MB,无网络连接,以后附加虚拟硬盘。
之后右键新创建的虚拟机,设置
BIOS中把IDE设为第一启动项
IDE控制器0中添加磁盘驱动器
选择物理硬盘,硬盘选择刚刚脱机的U盘
保存,连接虚拟机,启动虚拟机
完成!