《30天自制操作系统》学习笔记 day2 - 深入汇编语言与 Makefile 入门

Hervey Lv3

磨刀不误砍柴工

昨天初步实现了启动显示 hello, world 的功能,可喜可贺!

但是这样的开发方式仍然存在不少的问题。

一方面,昨天的程序依然是对于机器语言的简单翻译,并没有接触到真正核心的汇编语言,也没有发挥到汇编语言助记符“助记”的功能;

另一方面,每次制作系统镜像都要依次运行 asm.batinstall.batrun.bat 等批处理程序,着实有些麻烦。

所以,今天我们的工作就是进一步优化程序与开发流程。

程序优化

汇编语言除了 DBDWDDRESB 这类 数据定义类伪指令 助记符外,还有着许多其他类型的指令助记符,我们耳熟能详的就有 MOVADD 等。

所以,使用一些新的类型的指令,结合寄存器,我们能够将程序进一步进行去机器语言化:

helloos3.nas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
; hello-os
; TAB=4

ORG 0x7c00 ; 指明程序的装载地址

; 以下这段是标准AFT2格式软盘专用的代码

JMP entry
DB 0x90
DB "HELLOIPL" ; 启动区的名称可以是任意的字符串(8字节)
DW 512 ; 每个扇区(sector)的大小(必须为512字节)
DB 1 ; 簇(cluster)的大小(必须为1个扇区)
DW 1 ; FAT的起始位置(一般从第一个扇区开始)
DB 2 ; FAT的个数(必须为2)
DW 224 ; 根目录的大小(一般设成224项)
DW 2880 ; 该磁盘的大小(必须是2880扇区)
DB 0xf0 ; 磁盘的种类(必须是0xf0)
DW 9 ; FAT的长度(必须是9扇区)
DW 18 ; 1个磁道(track)有几个扇区
DW 2 ; 磁头数(必须是2)
DD 0 ; 不使用分区,必须是0
DD 2880 ; 重写一次磁盘大小
DB 0,0,0x29 ; 意义不明,固定
DD 0xffffffff ; (可能是)卷标号码
DB "HELLO-OS " ; 磁盘的名称(11字节)
DB "FAT12 " ; 磁盘格式名称(8字节)
RESB 18 ; 先空出18字节

; 程序核心

entry:
MOV AX,0 ; 初始化寄存器
MOV SS,AX
MOV SP,0x7c00
MOV DS,AX
MOV ES,AX

MOV SI,msg
putloop:
MOV AL,[SI]
ADD SI,1 ; 显示一个文字
CMP AL,0

JE fin
MOV AH,0x0e ; 显示一个文字
MOV BX,15 ; 指定字符颜色
INT 0x10 ; 调用显卡BIOS
JMP putloop
fin:
HLT ; 让CPU停止,等待指令
JMP fin ; 无限循环

msg:
DB 0x0a, 0x0a ; 2个换行
DB "hello, world"
DB 0x0a ; 换行
DB 0

RESB 0x7dfe-$ ; 填写0x00,直到 0x001fe

DB 0x55, 0xaa

; 以下是启动区以外部分的输出

DB 0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
RESB 4600
DB 0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
RESB 1469432

可以发现,作者在这里已经对程序的实现了初步的模块化,其中所涉及的新指令整理如下:

汇编指令/指令 来源 作用
ORG origin 伪指令,将程序装载到内存中指定的地址,根据 IBM 对内存的分配,引导程序应从 0x7c00 开始装载
JMP jump (无条件)跳转指令,无条件跳转到指定标签对应的内存地址
MOV move 赋值指令,将数据从一个位置复制到另一个位置,一般需要使用 BYTE ( 1 字节)、WORD ( 2 字节)、DWORD ( 4 字节) 指定数据
ADD add 加法指令,将两个操作数相加,结果存储到第一个操作数中
CMP compare 比较指令,比较两个操作数,设置标志寄存器 ZF 中(相同时 ZF=1 不同时 ZF=0
JE jump if equal 条件跳转指令,如果比较结果为相等( ZF = 1 ),则跳转到指定标签
INT interrupt 中断指令,触发指定的中断,这里调用 BIOS 中断 0x10 用于显示字符
HLT halt 停止指令,停止 CPU 执行,进入休眠状态,防止 CPU 无意义地空转

当然,这里已经开始使用寄存器进行数据的临时存储,因此在这里也整理了一下作者介绍的寄存器:

分类 名称 32 位寄存器 16 位寄存器 8 位寄存器 名称
通用寄存器 累加寄存器 accumulator EAX AX AL accumulator low
AH accumulator high
计数寄存器 counter ECX CX CL counter low
CH counter high
数据寄存器 data EDX DX DL data low
DH data high
基址寄存器 base EBX BX BL base low
BH base high
指针寄存器 栈指针寄存器 stack pointer ESP SP -
基址指针寄存器 base pointer EBP BP -
变址寄存器 源变址寄存器 source index ESI SI -
目的变址寄存器 destination index EDI DI -
段寄存器 附加段寄存器 extra segment - ES -
代码段寄存器 code segment - CS -
栈段寄存器 stack segment - SS -
数据段寄存器 data segment - DS -
- segment part 2 - FS -
- segment part 3 - GS -

除此之外,还有一个值得注意的语法: [] 表示的是内存地址,例如 [0x00] 代表内存中 0x00 位的地址。

开发流程优化 - Makefile 入门

这两天编写了不少程序,每次编写完汇编程序后,我们都需要通过作者提供的批处理文件和工具制作镜像文件并运行测试,这样的开发流程效率相对来说还是比较低的,是否有一种工具能让我们像正常开发项目一样通过一个或几个简单的命令完成整个工作流呢?作者由此引入了 make 这个强有力的开发工具,使用 Makefile 提高我们的编程效率。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# 默认动作

default :
../z_tools/make.exe img

# 文件生成规则

ipl.bin : ipl.nas Makefile
../z_tools/nask.exe ipl.nas ipl.bin ipl.lst

helloos.img : ipl.bin Makefile
../z_tools/edimg.exe imgin:../z_tools/fdimg0at.tek \
wbinimg src:ipl.bin len:512 from:0 to:0 imgout:helloos.img

# 命令

asm :
../z_tools/make.exe -r ipl.bin

img :
../z_tools/make.exe -r helloos.img

run :
../z_tools/make.exe img
copy helloos.img ..\z_tools\qemu\fdimage0.bin
../z_tools/make.exe -C ../z_tools/qemu

install :
../z_tools/make.exe img
../z_tools/imgtol.com w a: helloos.img

clean :
-del ipl.bin
-del ipl.lst

src_only :
../z_tools/make.exe clean
-del helloos.img

Makefile 的基础语法规则其实挺简单的:

1
2
target : dependencies
command

target 是目标,可以是一个具体的生成文件,也可以是一个命令(称为伪目标)。

dependencies 是依赖,指生成目标需要的文件,当依赖列表为空时 target 即为伪目标。

command 是命令,相当于批处理文件中的内容。

Makefile 可以理解为一个批处理文件的集合,我觉得现在很多工具例如 npmpipconda 都借鉴了 Makefile 的想法,并通过引入包的概念简化并加速了我们的开发流程。

后记

今天的代码量相比昨天小了不少,但是需要理解的东西越来越多了,只能说“磨刀不误砍柴工”吧,毕竟后续的开发会越来越复杂,没有易于维护的代码与方便的工具链可能会阻碍我们的开发工作。

  • 标题: 《30天自制操作系统》学习笔记 day2 - 深入汇编语言与 Makefile 入门
  • 作者: Hervey
  • 创建于 : 2025-03-03 21:26:18
  • 更新于 : 2025-03-04 04:32:48
  • 链接: https://herveyb3b4.github.io/2025/03/03/OSASK/OSASK-day2/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
目录
《30天自制操作系统》学习笔记 day2 - 深入汇编语言与 Makefile 入门