想法@IT·互联网操作系统

从零开发操作系统-第二天汇编语言、BIOS以及Makefile介

2024-11-06  本文已影响0人  shengjk1

你好,我是 shengjk1,多年大厂经验,努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注!你会有如下收益:

  1. 了解大厂经验
  2. 拥有和大厂相匹配的技术等

希望看什么,评论或者私信告诉我!

一、背景

其实也没有啥背景。
最主要的原因就像 《30天自制操作系统》一书作者说的那样,写一个操作系统,仅仅想想就是一件特别有趣的事情呢。一两年前曾经入手开始写过,但慢慢的就不了了之了。现在又有这个想法了,准备一直干下去,最终写一个操作系统出来,算是程序员生涯的一份礼物。

其次的原因,是因为我也认为未来初级程序员的岗位会越来越少,借助 LLM 人人都是初级程序员可能会变成现实。这个时候专业性和底层就会越来越重要

二、汇编介绍

《30天自制操作系统》一书中第二课的汇编语言,注释如下:

; hello-os
; TAB=4
; bootloader  code

        ORG     0x7c00          ; 指明程序装载地址  出厂的时候BIOS就被组装在电脑主板上的ROM单元里。电脑厂家在BIOS中预先写入了操作系统开发人员经常使用的一些程序

; 标准FAT12格式软盘专用的代码 Stand FAT12 format floppy code

        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扇区1440*1024/512)
        DB      0xf0            ; 磁盘类型(必须为0xf0)
        DW      9               ; FAT的长度(必??9扇区)
        DW      18              ; 一个磁道(track)有几个扇区(必须为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字节

; 程序主体

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

        MOV     SI,msg
putloop:
        MOV     AL,[SI]         ; [] 表示内存,表示把 SI对应的内存地址上数据的1个字节的内容读入到 AL 中。 MOV的数据传送源和传送目的地不仅可以是寄存器或常数,也可以是内存地址。 MOV会自动要求源数据和目标数据位数一致
        ADD     SI,1            ; 给SI加1
        CMP     AL,0
        JE      fin             ; 如果结果相等则跳转到指定地址,如果不等则不跳转
        MOV     AH,0x0e         ; 显示一个字符    INT 0x10, AH = 0xE -- display char,这是调用 BIOS 的 “Teletype Output” 功能,用于在屏幕上显示一个字符,并推进光标
        MOV     BX,15           ; 指定字符颜色
        INT     0x10            ; 调用显卡显示文字,INT 0x10 = Video display functions (including VESA/VBE)   INT软件中断指令
        JMP     putloop
fin:
        HLT                     ; 让CPU停止,等待指令
        JMP     fin             ; 无限循环

msg:                            ;0x7c74
        DB      0x0a, 0x0a      ; 换行两次
        DB      "hello, world"
        DB      0x0a            ; 换行
        DB      0

        RESB    0x7dfe-$        ; 填写0x00填充到0x7def, 有了 ORG,$代表将要读入的内存地址

        DB      0x55, 0xaa


; AX —— accumulator,累加寄存器          0-7位的低8位成为AL,8-15位的高8位称为 AH
; CX —— counter,计数寄存器
; DX —— data,数据寄存器
; BX —— base,基址寄存器                 通常在内存寻址中用来存放基地址。它与源索引SI和目的索引DI寄存器结合,可以用于访问数组或其他数据结构。
; SP —— stack pointer,栈指针寄存器      SP寄存器指向当前栈的顶部。在执行函数调用、参数传递、局部变量分配和函数返回时,栈指针会相应地增加或减少。
; BP —— base pointer,基地址指针寄存器    通常用于访问堆栈中的局部变量和函数参数。在栈帧中,BP通常指向帧的起始位置。
; SI —— source index,源变址寄存器       通常用于字符串操作和数组处理中,指向源数据的位置
; DI —— destination index,目的变址寄存器  同样用于字符串操作和数组处理,但它指向目标数据的位置
; 这些都是 16 位寄存器,所以可以存储16位的二进制. 按照机器语言中寄存器的编号顺序排列的
; 指令编码:操作码 opcode 和 操作数 operand 构成



; CPU中的8个8位寄存器,具体为:
; AL——累加寄存器低位(accumulator low)
; CL——计数寄存器低位(counter low)
; DL——数据寄存器低位(data low)
; BL——基址寄存器低位(base low)
; AH——累加寄存器高位(accumulator high)
; CH——计数寄存器高位(counter high)
; DH——数据寄存器高位(data high)
; BH——基址寄存器高位(base high)


; 段寄存器
; 这些段寄存器都是16位寄存器。
; ES——附加段寄存器(extra segment)
; CS——代码段寄存器(code segment)
; SS——栈段寄存器(stack segment)
; DS——数据段寄存器(data segment)
; FS——没有名称(segment part 2)
; GS——没有名称(segment part 3)

重点关注一下几个点:

  1. 通过汇编开发程序,被成为 Bootloader Code 具体 Bootloader 是什么以及在计算机启动过程中有啥作用,这篇文章有较为详细的介绍
  2. 程序的装在位置什么是:0x7c00
    这一块是 IBM 大叔们规定的,It should also be noted that your bootloader code is loaded and running in memory at physical addresses 0x7C00 through 0x7DFF.
  3. INT 0x10, MOV AH 0xE 表示 display char。这些都是在调用 BIOS function
  4. BIOS 在这篇文章中也有介绍
    这里再补充一下:BIOS 是计算机出厂时就被组装在电脑主板上的ROM单元里。电脑厂家在BIOS中预先写入了操作系统开发人员经常使用的一些程序。

三、Makefile

Makefile 是一个文本文件,用于控制自动化构建过程,特别是在软件开发领域。它是由 make 命令读取的脚本,用来指导编译器和链接器如何构建源代码、库和其他依赖项。

Makefile 通常包含以下元素:

  1. 目标(Targets):Makefile 中的目标通常是最终要生成的文件,比如可执行程序或库文件。
  2. 依赖关系:每个目标可以有零个或多个依赖项,这些依赖项是该目标所依赖的其他目标和文件的列表。
  3. 命令:当目标的依赖项比目标本身更新时,需要执行的命令列表,例如编译器的编译指令等。
  4. 变量:用于简化 Makefile 的维护和增强其可读性的名称/值对。
  5. 自动变量和模式规则:用于进一步抽象常见的构建任务。
  6. 隐含规则:make 提供了一些内置的规则和变量,可用于常见的目标类型,如 .o 文件和可执行文件。

Makefile 的语法相对简单,但是非常强大且灵活,可以适应各种复杂的构建场景。对于大型项目来说,手工编译每一个模块不仅费时而且容易出错,而 Makefile 可以帮助自动化这一过程,确保项目的各个部分按照正确的顺序和规则进行编译和链接。

在实际的开发环境中,尤其是涉及 C/C++ 语言的项目中,Makefile 被广泛使用。此外,许多现代构建系统和包管理器(如 CMake、GNU Build System 等)也支持或生成为旧版 make 系统编写的 Makefile。

四、BIOS 扩展

BIOS(基本输入输出系统)是一种固件,它既不属于纯粹的软件也不完全是硬件。固件是介于软件和硬件之间的一种特殊形式,它通常被编程到计算机主板上的一块闪存或EPROM芯片中。BIOS负责在计算机启动时初始化硬件,并提供一个到操作系统的桥梁,使得计算机能够加载操作系统。虽然BIOS在功能上类似于软件,但它的存储和执行方式又与硬件相似,因此它被看作是一种固件。

BIOS(基本输入输出系统)的概念最初是在1975年由Gary Kildall为Intel 8080微处理器设计的CP/M操作系统(Control Program/Monitor)的一部分而产生的。以下是BIOS发展的一些关键点:

  1. CP/M操作系统:Gary Kildall创建的CP/M操作系统需要一个方法来与不同的硬件进行通信。为了解决这个问题,他设计了一个BIOS,它包含了一系列底层硬件接口的例程,这些例程可以被CP/M调用以执行输入输出操作。
  2. IBM PC的推出:1981年,IBM推出了第一台个人计算机IBM PC。为了使软件开发变得更加容易,IBM决定在其PC上使用BIOS来提供一个标准的硬件接口。这样,软件开发者就可以编写应用程序,而不必担心与各种硬件的直接交互。
  3. BIOS的作用:在IBM PC中,BIOS负责在计算机启动时执行POST(电源自检)来检查硬件配置,初始化硬件组件,并提供一个引导加载程序来从磁盘或其他存储设备加载操作系统。
  4. 兼容性和标准化:随着IBM PC及其兼容机的普及,BIOS成为行业标准。其他硬件制造商开始为他们的主板编写兼容的BIOS,以保持与IBM PC软件的兼容性。
  5. BIOS的发展:随着时间的推移,BIOS的功能不断扩展,以支持新的硬件技术和功能。尽管后来UEFI(统一可扩展固件接口)开始逐渐取代传统的BIOS,但BIOS的概念和基本功能仍然在现代计算机系统中发挥着作用。

BIOS的产生是计算机历史上一个重要的里程碑,它为硬件和软件之间的标准化交互奠定了基础,并且极大地推动了个人计算机的普及和发展。

五、总结

通过汇编语言的介绍,作者展示了操作系统开发的基础,包括Bootloader Code的重要性和BIOS在计算机启动过程中的作用。Makefile的自动化构建过程和BIOS的历史发展也被详细阐述,为读者提供了计算机系统开发的深入理解。

上一篇 下一篇

猜你喜欢

热点阅读