Day02

汇编语言学习与makefile入门

在进入版本迭代之前,先学习一下汇编语言。

汇编语言的一些简单指令

MOV move, 可以类似理解为赋值
CMP compare, 比较两个数
JE jump if equal
ADD add
INT interrupt
HLT halt
ORG origin 指明程序装载的地址
[] 取地址
BYTE 8bit
WORD 16bit
DWORD 32bit

一些寄存器

有代表性的寄存器

AX accumulator 16bit
AL/AH 8bit
EAX 32bit
CX counter(PC)
CL/CH
ECX
DX data(DR) 数据寄存器
DL/DH
EDX
BX base 基址寄存器
BL/BH
EBX
SP stack pointer 栈指针寄存器
ESP
BP base pointer 基址指针寄存器
EBP
SI source index 源变址寄存器
ESI
DI detination index 目的变址寄存器
EDI

段寄存器

ES extra segment 附加段寄存器
CS code segment 代码段寄存器
SS stack segment 栈段寄存器
DS data segment 数据段寄存器
FS segment part 2 没有名称
GS segment part 3 没有名称

添加了标签、一些汇编语言助记符

helloos3

节省空间起见,等今天的代码全都写完了放一个完整的吧。

仅需要制作启动区

helloos4

我们仅需要制作启动区,剩下的可交给以后的磁盘映像管理工具来做。因此截去了代码的后半部分,留到以后再说。

加入makefile

helloos5

makefile以前在写c语言的时候也用过,这里有了更广泛的应用。本质上即为一定文件的依赖关系:当一些文件改变时候,执行一定的指令。

makefile的一个坑

makefile的缩进需要使用tab,用空格会误认为不是指令,导致不能make。
——在比对两个文件许多次之后才知道。。

代码整合

ipl.nas:

; hello-os
; TAB=4
    ORG 0x7c00 ; origin 指明程序的装载地址
; 以下这段是标准FAT12格式软盘专用的代码

    JMP entry
    ; define byte : 一字节
    DB  0x90
    ; 该汇编语言下DB可以直接写字符串
    DB "HELLOIPL" ; 启动区的名称可以是任意的字符串(8字节)
    ; define word : 2字节
    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)有几个扇区(必须是18)
    DW 2 ; 磁头数(必须是2)
    ; define double word : 4字节
    DD 0 ; 不使用分区(必须是0)
    DD 2880 ; 重写一次磁盘的大小
    DB 0, 0, 0x29 ; 意义不明,固定
    DD 0xffffffff ; (可能是)卷标号码
    DB "HELLO-OS   " ; 磁盘的名称(11字节)
    DB "FAT12   " ; 磁盘格式名称(8字节)
    ; reserve byte 空出一定数量字节
    RESB 18 ; 先空出18字节

; 程序核心

entry:
    MOV AX, 0 ; 初始化寄存器 AX = 0, AX:accumulator (ACC)
    MOV SS, AX
    MOV SP, 0x7c00
    MOV DS, AX
    MOV ES, AX
    MOV SI, msg
putloop:
    MOV AL, [SI]
    ADD SI, 1 ; 给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 ; 换行两次
    DB "hello world"
    DB 0x0a ; 换行
    DB 0

    ; 书上不给这两行是什么意思。。
    RESB 0x7dfe-$ ;

    DB 0x55, 0xaa

; 截掉后半部分

makefile:


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