《操作系统30天》-合川秀实-学习日志day2

 一、文本编辑器

上一篇提到这个notepad++,网上下载,默认语言选择中文,安装好之后界面如下

如果用Notepad++打开.nas文件,比如说我们的helloos3中的helloos.nas文件,打开之后代码部分是可以正常显示的,但是注释部分显示的是日文,可能是因为这款编辑器的日本开发的吧,这不影响我们使用,注释部分书本上都有。

二、继续开发—学习相关知识

1、Helloos.nas中的程序核心部分

; hello-os
; TAB=4

		ORG		0x7c00			; 指明程序的装载地址
; 以下的记述用于标准FAT12格式的软盘

		JMP		entry
		DB		0x90
----(中略)----
;  程序核心
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			; 给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

entry,putloop,fin,msg用于指定JMP指令的跳转目的地

2、部分新指令:ORG , JMP , MOV , INT , HLT

ORG指令:来源于”origin”,这个指令告诉nask,程序要从指定的这个地址(0x7c00)   开始,把程序装载带内存中的这个地址。有了这条指令美元符($)代表将要读入的内  存地址。

JMP指令:相当于C语言的goto语句,跳转指令。

MOV指令:赋值,”MOV AX,0” 相当于” AX=0; ”,要求源数据和目的数据必须位数相同。

INT指令:软件中断指令,BIOS程序在电脑出厂时组装在主板上的ROM里,里面写入    了操作系统开发人员经常用到的程序(各种函数的集合)。INT就是用来调用这些函    数的指令,INT后面跟数字,不同的数字可以调用不同的函数。

HLT指令:停止指令,让CPU进入待机状态,任一操作都可以唤醒CPU。

3、16位、32位寄存器,段寄存器

  • 16位具有代表性的寄存器(存储16位二进制数),前四个寄存器名字后的X代表扩展的意思(extend),其次,下面寄存器的排列顺序是按照机器语言中的寄存器的编号排列的。这八个寄存器全部合起来只有16个字节,CPU把全部的寄存器都用上也只能存16个字节。

AX—accumulator , 累加寄存器

CX—counter , 计数寄存器

DX—data , 数据寄存器

BX—base , 基址寄存器

SP—stack pointer , 栈指针寄存器

BP—base pointer , 基址指针寄存器

SI—source index , 源变址寄存器

DI—destination index , 目的变址寄存器

 

  • 八个特殊的8位寄存器,比如说AX寄存器有16位,其中0-7位的第八位称为AL,而8-15位的高八位称为AH。在上面八个16位寄存器中,SP,BP,SI,DI没有分”L”, ”H” 如果要取高低八位,就要用“MOV  AX, SI”将SI的值赋值到AX中,再用AH,AL来取值。这些寄存器不能扩展CPU的存储能力,CPU还是只能存储16个字节。

AL—accumulator low , 累加寄存器低位

CL—counter low , 计数寄存器低位

DL—data low , 数据寄存器低位

BL—base low , 基址寄存器低位

AH—accumulator high , 累加寄存器高位

CH—counter high , 计数寄存器高位

DH—data high , 数据寄存器高位

BH—base high , 基址寄存器高位

 

32位寄存器就是在16位寄存器的名字前面加上一个E(表示extend):

EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI

  • 作者还提到一种16位的段寄存器,书本上没有描述其作用,我百度了一下其作用。段寄存器是根据内存分段的管理模式而设置的。内存单元的物理地址由段寄存器的值和一个偏移量组合而成的,这样可用两个较少位数的值组合成一个可访问较大物理空间的内存地址。有点类似于硬盘分页,因为计算机对内存分段管理,以分配给不同的程序使用,需要用8个字节(64位)存储这些信息,但是16位的段寄存器只能存储段号,再由段号映射到存在内存中的GDT(全局段号记录表),读取段信息。

ES— extra segment 附加段寄存器

CS— code segment 代码段寄存器

SS— stack segment 栈段寄存器

DS— data segment 数据段寄存器

FS— segment part2 没有名称

GS— segment part3 没有名称

 

4、指令具体操作的基础知识和汇编语言的理解

; hello-os
; TAB=4

		ORG		0x7c00		; 指明程序的装载地址(程序从0x7c00开始)
; 以下的记述用于标准FAT12格式的软盘

		JMP		entry            ;跳转(执行)到0x7c50地址的程序
		DB		0x90
----(中略)----
;  程序核心
entry:
		MOV		AX,0		; 初始化寄存器为0
		MOV		SS,AX
		MOV		SP,0x7c00
		MOV		DS,AX
		MOV		ES,AX

		MOV		SI,msg           ;把msg的地址放到寄存器中
  • 这里插入一点内存和CPU的知识:内存是CPU能唯一直接访问的大型存储介质,对CPU来说内存是外部存储器,CPU通过指令发出控制信号(通过管脚向内存发送电信号),实现对内存的读写操作。程序保存在内存中,CPU在执行机器语言时,必须从内存中一个个地读出命令,按顺序执行。不过CPU访问内存的速度比访问寄存器慢得多,所以我们之前还学到一个高速缓存(cache),主要是用来加快CPU访问速度的。
  • MOV指令可以指定数据大小,比如说BYTE , WORD , DWORD 等汇编语言保留字。拿书上例子来说MOV BYTE  [678] ,123 指令是用“678”号地址保存“123”这个数值,1byte就是八位,相当于某八个存储单元存了代表“123”的开或关的电信号。“数据大小 [地址] ”是一个固定的组合,如果是MOV WORD  [678],123 就相当于把123当成一个16位的二进制数值,保存在地址678,679这两个位置里。如果是DWORD就是相邻(地址增加方向)的两个字节都保存了123这个数。MOV WORD  [678],123执行过程如图所示:

内存地址的指定方法除了用常数之外还可以用寄存器,但是只有BX, BP, SI, DI这四个寄存器可以用来指定内存。原因是CPU只能处理这四个指令的机器语言。“BYTE[SI]”如果SI中保存的是789,则BYTE[SI]就是BYTE[789]的意思,所以MOV AL, BYTE[SI] 就是将SI地址的1字节内容读到AL,根据MOV指令的规则,可以省略byte就变成了下面的MOV  AL,[SI]。

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
  • 这个 [SI] 表示内存地址,因为MOV指令的源数据和目的数据位数相同,即AL寄存器可存放位数刚好等于SI的内存地址的位数。CMP指令是一个比较作用,AL中的数值与0相比,如果AL=0; goto fin; JE指令是结果相等则跳转
  • 显示字符要跟显卡联系起来,INT 0x10是调用的0x10(16)号函数,在操作系统中控制显卡。查阅BIOS网页得出显示一个字符的格式:
  • AH=0x0e;
    AL=character code;
    BH=0;
    BL=color code;
    返回值:无

    注意:beep、退格(back space)、CR、LF都会被当做控制字符处理

    值得注意的是,BL中放入了彩色字符码,而我们这里赋值的是给BX,改变了BL的值,作者尝试修改颜色但只能显示白色,实际上的原因是这个窗口不能显示其他颜色字体,我们每次的run都是显示黑底白字,关于怎么显示其他颜色字体,书本后面会有介绍到。

fin:
		HLT						; 让CPU停止
		JMP		fin				; 无限循环

msg:
		DB		0x0a, 0x0a		; 换行2次
		DB		"hello, world"
		DB		0x0a			; 换行
		DB		0
  • 解读fin:前面的HLT指令是让CPU进入待机状态的指令,只要外部发生变化,就会继续执行程序,但其实HLT指令的下一句就是死循环跳转指令,所以不写HLT指令也是可以的。不过如果没有HLT指令,CPU就一直处于运作状态,耗电太大,考虑到资源问题所以加上HLT指令是一个很好的习惯。

5、C语言改写后的helloos.nas节选

Entry:
    AX=0;
    SS=AX;
    SP=0x7c00;
    DS=AX;
    ES=AX;
    SI=msg;
Putloop:
    AL=BYTE[SI];
    SI=SI+1;
    If( AL==0 ) { goto  fin; }
    AH=0x0e;
    BX=15;
    INT 0x10;
    goto putloop;
Fin:
    HLT;
    goto fin; 

6、关于0x00007c00的理解

  • 内存的0号地址,是BIOS程序用来实现各种不同功能的地方,如果我们随便用的话,就会与BIOS发生冲突。另外,在内存的0xf0000号地址附近,还存放着BIOS本身,那里我们也不能用。作者给出一个网站上面有个“地图”,其实解释这个地方的一句话就是0x00007c00-0x00007dff:启动区内容的装载地址 程序中的ORG指令的值就是这个数字,这个是开发者在做BIOS就规定好的,所以就按照规则用从0x00007c00开始写就好了。

三、线制作启动区

启动区只需要512个字节,吧helloos.nas的后半部分截掉,保留512个字节,把文件名改写成ipl.nas,按以下步骤操作!我这里是手动截取,在创新点里面有提到,直接把helloos.nas转化成txt文件截取之后再保存为ipl.nas文件,保存到我新建的helloos5文件夹中。截图见创新点。

操作步骤:为了方便,可以直接复制helloos4文件夹到tolset中,打开文件夹再打开asm.bat文件,生成以下两个文件,再用makeimg.bat文件生成helloos.img文件然后运行。

四、Makefile入门

先用记事本文本编辑器写入以下内容,保存之后再把.txt后缀名去掉,就变成了Makefile不带扩展名文件。

根据书本上解释:ipl.bin : ipl.nas Makefile—制作ipl.bin之前检查ipl.nas和Makefile文件是否准备好,如果有这两个文件就执行下一行,下面的helloos.img也是一样的写法,\是续行符号。需要从tolset的z_new_w文件夹中复制make.bat过来制作make.exe。此时文件夹里应该有这些文件:

 

用!Cons打开一个命令行窗口,输入“make -r ipl.bin”启动make.exe,它首先读取Makefile文件,寻找制作ipl.bin的方法,make.exe找到制作方法之后去执行其中的命令顺利生成ipl.bin,然后我们再输入“make -r helloos.img”启动make.exe按照指令执行。

如果删除helloos.img和ipl.bin之后输入“make -r helloos.img”命令,make会生成helloos.img文件,其中会先去Makefile寻找ipl.bin的生成方法,生成ipl.bin在生成helloos.img。

如果不删除文件,再输入命令“make -r helloos.img”执行:

修改ipl.nas的输出信息“How are you?”保存,先保持ipl.bin和helloos.img刚刚的样子不变,这时再重新输入“make -r helloos.img”命令,发现输出为“How are you?”说明make冲会重新生成输出文件!

 

改进:在Makefile文件里加入

img :

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

修改之后,我们只需要输入“make img”就可直接生成helloos.img了,此时可以删掉making.bat,再加入下面这些:

asm :

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

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

加入之后,“run.bat”、“install.bat”都用不着了,现在只需要在命令窗口输入“make run”它就会首先执行“make img”, 然后再启动模拟器。也就是说,现在如果删除刚刚生成的文件之后,直接输入“make run”就可以显示输出文字啦!什么都没有,然后输入“make run”指令,显示字符我修改过。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值