makefile中运行shell命令(第02天汇编语言makefile入门30天自制操作系统学习笔记)
除了txt文本编辑器,我们也可以使用第三方。比如,我喜欢用的vscode:https://code.visualstudio.com
继续开发将之前的改写成更简单易懂的形式
; hello-os
; TAB=4 缩进4个字节
ORG 0x7c00 ; 指明程序的装载地址, 0x00007c00-0x00007dff
; setup: 标准FAT12格式软盘专用代码
JMP entry ; 跳转到0x7c50地址
DB 0x90 ; 意义不明,固定
DB "HELLOIPL" ; 启动区名称 = 任意字符串 = 8个字节 (必须)
DW 512 ; 1个扇区(sector)的大小 = 32*16 =512个字节(必须)
DB 1 ; 簇(cluster)的大小 = 1个扇区(必须)
DW 1 ; FAT的起始位置 = 第一个扇区(通常)
DB 2 ; FAT的个数 = 2(必须)
DW 224 ; 根目录的大小 = 244项(通常)
DW 2880 ; 该磁盘大小 = 2880个扇区(必须)
DB 0xf0 ; 磁盘种类 = 0xf0(必须)
DW 9 ; FAT的长度 = 9个扇区(必须)
DW 18 ; 1个磁道(track)= 18个扇区(必须)
DW 2 ; 磁头数 = 2个(必须)
DD 0 ; 不使用分区 = 0(必须)
DD 2880 ; 重写1次 = 磁盘大小
DB 0,0,0x29 ; 意义不明,固定
DD 0xffffffff ; 卷标号码(猜测)
DB "HELLO-OS " ; 磁盘名称 = 11个字节(必须)
DB "FAT12 " ; 磁盘格式名称 = 8字节(必须)
RESB 16 ; 空出 = 16字节(必须),作者这里写成18了,应该是8*8=16个字节
; 程序核心
entry: ; 声明,类似void entry(){ }
MOV AX,0 ; AX = 0
MOV SS,AX ; SS = AX = 0
MOV SP,0x7c00 ; SP =0x7c00
MOV DS,AX ; DS = AX = 0
MOV ES,AX ; ES = AX = 0
MOV SI,msg ; SI = msg
putloop: ; 声明,类似void putloop(){ }
MOV AL,[SI] ; AL = [内存SI]
ADD SI,1 ; SI = SI 1
CMP AL,0 ; AL =? 0 比较大小
JE fin ; 如果AL==0,那么跳转到fin功能
MOV AH,0x0e ; 显示一个文字(0x0e)
MOV BX,15 ; BX = 15 指定字符颜色
INT 0x10 ; 中断指令,调用BIOS控制显卡
JMP putloop ; 跳转到putloop功能
fin: ; 声明,类似void fin(){ }
HLT ; 让CPU停止,等待指令
JMP fin ; 无限循环
msg: ; 声明,类似void msg(){ }
DB 0x0a, 0x0a ; 换2行
DB "hello, world"
DB 0x0a ; 换1行
DB 0
RESB 0x7dfe-$ ;$含义变了
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=源头,告诉nask,在开始执行时,把这些机 器语言指令装载到内存中的指定地址。
如果没有它,有几个指令就不能被正确地翻译和执行。另外,有了这条指令的话,
美元符($)的含义 也随之变化,不再是指输出文件的第几个字节,
而是代表将要读入的内存地址。
JMP 跳转
entry “入口”的意思,标签声明,指定JMP跳转的目的地
MOV 赋值, 就是= , MOV AX,0相当于AX=0另一个规则,源数据和目的数据必须位数相同。
也就是说,能向AL里代入的就只有BYTE,这样一来就可以省略 BYTE,
即可以写成: MOV AL, BYTE [SI] MOV AL, [SI]
ADD 加法指令 ADD SI,1 就是SI = SI 1
CMP compare 比较指令 if(a==3){处理...} CMP AL,0 将AL与0比较
JE jump if equal 条件指令,如果AL==0 那么跳转到fin
INT interrupt,中断指令 BIOS是英文“basic input output system”的缩写,
“基本输入输出系统(程序)”。 只读存储器,不能写入,切断电源以后内容不会消失。
ROM 是“read only memory”的缩写。 BIOS功能非常多,为操作系统开发人员
准备的各种函数的集合。而INT就 是用来调用这些函数的指令。INT的后面是个数字,
使用不同的数字可 以调用不同的函数。这次我们调用的是0x10(即16)号函数,
它的功能 是控制显卡。
HLT halt ,让CPU待机指令, 让CPU毫无意义地空转,或者不停地执行JMP指令,
这会使CPU的负荷达到100%,非常费电
存储32位bit4个字节extend扩展 |
存储16位bit2个字节extend扩展 |
存储8位bit1个字节high高位 |
存储8位bit1个字节low低位 |
备注 |
EAX0位~ 7位=低位AX8位~15位=高位? |
AX0位~ 7位=低位AL8位~15位=高位AH |
AH |
AL |
accumulator累加寄存器 |
ECX0位~ 7位=低位CX8位~15位=高位? |
CX0位~ 7位=低位CL8位~15位=高位CH |
CH |
CL |
counter计数寄存器 |
EDX0位~ 7位=低位DX8位~15位=高位? |
DX0位~ 7位=低位DL8位~15位=高位DH |
DH |
DL |
data 数据寄存器 |
EBX0位~ 7位=低位BX8位~15位=高位? |
BX0位~ 7位=低位DL8位~15位=高位DH |
BH |
BL |
base 基址寄存器 |
ESP |
SP |
stack pointer 栈 指针寄存器 | ||
EBP |
BP |
base pointer 基址 指针寄存器 | ||
ESI |
SI |
source index,源 变址寄存器 | ||
EDI |
DI |
destination index, 目的 变址寄存器 | ||
ES |
extra segment register 附加段寄存器 | |||
CS |
code segment regsiter 代码段寄存器 | |||
SS |
stack segment 栈段寄存器 | |||
DS |
data segment 数据段寄存器 | |||
FS |
segment part 2 没有名称 | |||
GS |
segment part 3没有名称 |
表格中的内容就是不同CPU的可用变量,少的可怜只有16个字节。
BP、SP、SI、DI怎么没分为“L”和“H”呢?如果要分别取高位或低位数据的话,就必须先用“MOV,AX, SI”将SI的值赋到AX中去,然后再用AL、AH来取值。这貌似是英特尔 (Intel)的设计人员的思维模式
MOV BYTE [678],123 用内存的“678”号地址来保存“123”这个数值,数据大小 [地址] 这是一个固定的组合。
用寄存器来指定内存地址,只有BX、BP、SI、DI这几个。剩下的AX、CX、DX、SP不能用来指定内存地址,这是因为CPU没有处理这种指令的电路(机器语言)所以想把DX内存里的内容赋值给AL 的时候,就会这样写:
MOV BX, DX
MOV AL, BYTE [BX]
目前来看,进一步优化的汇编文件,看起来让人晕头转向
制作启动区磁盘容量有限,我们还要增加很多功能,所以前512字节作为启动区,剩下的部分我们用磁盘映像管理工具来做
删掉:helloos.nas文件中的512字节之后的内容(还记得怎么确定512字节吗?0x55,0xaa就是标志,下面的代码都删掉)
既然只作为启动区文件,名字要起的高大上一点,helloos.nas改成ipl.nas
既然helloos.nas改名了,asm.bat内容也得改改
..\z_tools\nask.exe ipl.nas ipl.bin ipl.lst
代码意思:基于ipl.nas文件,生成了ipl.bin和ipl.lst两个文件
我们要基于ipl.bin文件生成helloos.img文件新建:makeimg.bat文件,填写如下内容(先创建txt文件,再改后缀为bat)
..\z_tools\edimg.exe imgin:../z_tools/fdimg0at.tek wbinimg src:ipl.bin len:512 from:0 to:0 imgout:helloos.img
此时文件夹内有5个文件
启动顺序如下:
- cmd.bat
- 输入asm,回车(生成ipl.bin和ipl.lst)
- 输入makeimg,回车 (生成helloos.img)
- 输入run,回车
此时文件夹内的状况
这么多文件!!!
bat文件基本都是一行代码!
能不能弄成一个文件?
makefile入门
新建:Makefile文件,把多个bat文件内容复制过来(如何创建Makefile文件?创建txt文件,把后缀删掉,不要后缀)
#这是asm.bat内容
ipl.bin : ipl.nas Makefile
../z_tools/nask.exe ipl.nas ipl.bin ipl.lst
#这是makeimg.bat内容
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
新建:make.bat文件,并输入以下内容
..\z_tools\make.exe %1 %2 %3 %4 %5 %6 %7 %8 %9
测试:启动cmd,输入make -r ipl.bin
测试:启动cmd,输入make -r helloos.img
整了半天,还需要输入这么长的代码,犹如脱裤子放屁!
为了减少在cmd中输入,我们继续改造Makefile
#这是asm.bat内容
ipl.bin : ipl.nas Makefile
../z_tools/nask.exe ipl.nas ipl.bin ipl.lst
#这是makeimg.bat内容
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代替 make -r ipl.bin指令
asm :
../z_tools/make.exe -r ipl.bin
#用img代替 make -r helloos.img指令
img :
../z_tools/make.exe -r helloos.img
从现在开始,我们只需要输入make asm和make img 即可以得到三个文件
我们把run.dat内容也复制进去,只要在cmd 输入make run即可运行虚拟机
#-------------------------------下面是生成指令-------------------------------
#这是asm.bat内容
ipl.bin : ipl.nas Makefile
../z_tools/nask.exe ipl.nas ipl.bin ipl.lst
#这是makeimg.bat内容
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代替 make -r ipl.bin指令
asm :
../z_tools/make.exe -r ipl.bin
#用img代替 make -r helloos.img指令
img :
../z_tools/make.exe -r helloos.img
#这是run.dat文件内容,本质上就是三个指令,所以和命令放在一起
run :
../z_tools/make.exe img
copy helloos.img ..\z_tools\qemu\fdimage0.bin
../z_tools/make.exe -C ../z_tools/qemu
除了生成文件,也可以删除文件
#-------------------------------下面是生成指令-------------------------------
#这是asm.bat内容
ipl.bin : ipl.nas Makefile
../z_tools/nask.exe ipl.nas ipl.bin ipl.lst
#这是makeimg.bat内容
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代替 make -r ipl.bin指令
asm :
../z_tools/make.exe -r ipl.bin
#用img代替 make -r helloos.img指令
img :
../z_tools/make.exe -r helloos.img
#这是run.dat文件内容,本质上就是三个指令,所以和命令放在一起
run :
../z_tools/make.exe img
copy helloos.img ..\z_tools\qemu\fdimage0.bin
../z_tools/make.exe -C ../z_tools/qemu
#-------------------------------下面是生成指令删除-------------------------------
clean :
-del ipl.bin
-del ipl.lst
src_only :
../z_tools/make.exe clean
-del helloos.img
每次都要输入make run。能不能设置默认指令,点点就可以执行?
最开头增加default命令
#-------------------------------下面是默认指令-------------------------------
default :
../z_tools/make.exe img
#-------------------------------下面是生成指令-------------------------------
#这是asm.bat内容
ipl.bin : ipl.nas Makefile
../z_tools/nask.exe ipl.nas ipl.bin ipl.lst
#这是makeimg.bat内容
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代替 make -r ipl.bin指令
asm :
../z_tools/make.exe -r ipl.bin
#用img代替 make -r helloos.img指令
img :
../z_tools/make.exe -r helloos.img
#这是run.dat文件内容,本质上就是三个指令,所以和命令放在一起
run :
../z_tools/make.exe img
copy helloos.img ..\z_tools\qemu\fdimage0.bin
../z_tools/make.exe -C ../z_tools/qemu
#-------------------------------下面是生成指令删除-------------------------------
clean :
-del ipl.bin
-del ipl.lst
src_only :
../z_tools/make.exe clean
-del helloos.img
这个时候,只需要输入make然后回车,即可生成三个文件
其实,咱们现在双击make.bat文件,即可生成三个文件,连cmd都不用打开
好了,第二天的内容就到这里
,
免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com