《30天自制操作系统》学习笔记 day2 - 深入汇编语言与 Makefile 入门
磨刀不误砍柴工
昨天初步实现了启动显示 hello, world 的功能,可喜可贺!
但是这样的开发方式仍然存在不少的问题。
一方面,昨天的程序依然是对于机器语言的简单翻译,并没有接触到真正核心的汇编语言,也没有发挥到汇编语言助记符“助记”的功能;
另一方面,每次制作系统镜像都要依次运行 asm.bat 、install.bat 、 run.bat 等批处理程序,着实有些麻烦。
所以,今天我们的工作就是进一步优化程序与开发流程。
程序优化
汇编语言除了 DB 、 DW 、 DD 、 RESB 这类 数据定义类伪指令 助记符外,还有着许多其他类型的指令助记符,我们耳熟能详的就有 MOV 、 ADD 等。
所以,使用一些新的类型的指令,结合寄存器,我们能够将程序进一步进行去机器语言化:
1 | ; hello-os |
可以发现,作者在这里已经对程序的实现了初步的模块化,其中所涉及的新指令整理如下:
| 汇编指令/指令 | 来源 | 作用 |
|---|---|---|
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 | # 默认动作 |
Makefile 的基础语法规则其实挺简单的:
1 | target : dependencies |
target 是目标,可以是一个具体的生成文件,也可以是一个命令(称为伪目标)。
dependencies 是依赖,指生成目标需要的文件,当依赖列表为空时 target 即为伪目标。
command 是命令,相当于批处理文件中的内容。
Makefile 可以理解为一个批处理文件的集合,我觉得现在很多工具例如 npm 、 pip 、 conda 都借鉴了 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 进行许可。