第2天
计算机架构
内存
P34CPU的存储能力很差,如果想让它处理大数据,就必须给它另外准备一套用于存储的电路。即使32位CPU,把所有寄存器
加在一起也最多只能存储32位个字节的数据。就算再加上全部段寄存器,也只有44字节。这么小,就连启动电脑的启动
区数据都装不下。
内存实际是外部存储器,CPU通过自己的一部分管脚(引线)向内存发送电信号,CPU和内存之间还有称为芯片的控制单元。
CPU和内存的电信号交换,并不仅是为了存取数据。从根本讲,程序也是存储在内存里的。
CPU访问内存的速度比访问寄存器慢很多倍,记住这一点,我们才能开发出执行速度快的程序来。
P40
大家所有的内存是想怎么用就怎么用的?不是这样的。内存的0号地址,也就是最开始部分,是BLOS程序实现不同功能的地方。如果我们随便使用。就会与BLOS发生冲突,结果不止BLOS出错,我们的程序也肯定会问题百出.另外在内存的0xf0000号地址附近,还存放着BLOS程序本身,那里也不能使用.
内存中还有其它地方不能使用.
0x7c00
P400x00007c00-0x00007dff:启动区内容的装载地址
为什么是0x7c00? 0x7000不是更简单,好记?没办法,当初规定的就是0x7c00,做出这个规定的应该是IBM的大叔们,估计他们现在都成爷爷了。
BIOS
P38出厂时就组装在电脑主板上的ROM单元里。英文"basic input output system",直译过来就是“基本输入输出系统”
最近的BIOS功能非常多,甚至包括了电脑的设定画面,不过它的本质正如其名,就是为操作系统开发人员准备的各种函数集合。
而INT就是用来调用这些函数的指令。INT的后面是个数字,使用不同的数字可以调用不同的函数。
INT 0x10(即16)号函数,它的功能是控制显卡。
汇编
ORG指令
P30这个指令告诉nask,在开始执行时把这些机器语言指令装载到内存中哪个地址,如果没有它有几个指令就不能被正确的翻译和执行。
另外有了这条指令的话,美元符($)的含义发生变成,不再是输出文件的第几个字节,而是将要读入的内存地址。
来源于英文"origin",意思是“源头,起点”。它会告诉nask,程序要从指定的这个地址开始,也就是要把程序装载到内存中的指定地址。
ORG 0x7c00?
P39换成其它行不行?还真不行,把它换成1234的话,程序马上就不动了。参见,计算机架构>0x7c00
JMP指令
P30相当于C语言的goto语句,来源于英文的jump,意思是跳转。
"entry:"标签的声明
P30
用于指定JMP指令的跳转目的地,这与C语言很像。
MOV指令
P30应该是最常用的指令了,这个指令非常简单,即赋值。"MOV AX,0",相当于"AX=0;",这样一个赋值语句。
源自英文"move",意思是“移动”。但是执行"MOV SS,AX"后,AX并没变空,还保留原来的值,所以这实际是赋值,而不是“移动”。
P37
MOV指令有个规则就是源数据和目的数据必须位数相同。
AX和SS
P31CPU中名为寄存器的存储电路,在机器语言中就相当于变量的功能。
AX----accumulator,累加寄存器
CX----counter,计数寄存器
DX----data,数据寄存器
BX----base,基址寄存器
SP----stack pointer,栈指针寄存器
BP----base pointer基址指针寄存器
SI----source index源变址寄存器
DI----destination index目的变址寄存器
这8个寄存器(16位)不管用哪一个都差不多能进行同样的计算,但如果都用AX来进行各种计算的话,程序就可以写得很简洁。
CX,为方便计数而设计,BX则适合作为计算内存地址的基点。其它寄存器也各有优点。
AX,CX,DX,BX,这个X表示扩展(extend)的意思.
这几个寄存器的排列顺序是按照机器语言中寄存器的编号顺序排列的.
这个8个寄存器全部合起来也只有16个字节.就算把这8个寄存器都用上,CPU也只能存储区区8个字节。
8位寄存器
P32AL----累加寄存器低位accumulator low
CL----计数寄存器低位counter low
DL----数据寄存器低位data low
BL----基址寄存器低位base low
AH----累加寄存器高位accumulator high
CH----计数寄存器高位counter high
DH----数据寄存器高位data high
BH----基址寄存器高位base high
AX寄存器 H- -L
AX寄存器共16位,0位到7位低8位称为AL,而8位到15位的高8位称为AH
BP,SP,SI,DI不能分为"L"和"H",如果非要分高位,低位的话。就必须先用"MOV, AX, SI"将SI的值赋到AX中去,
然后再用AL,AH来取值,这好像是英特尔的设计人员思维模式
EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI
P33这些就是32位寄存器.这个字母E还是来源于"Extend"(扩展)这个词.
EAX中低16位就是AX,但高16位没有名字,也没有编号。也就是,虽然可能把EAX当作2个16位寄存器使用,
但只有低16位用起来方便;如果要用高16位,就需要移位命令,把高16位移到低16位后才行。
这么说32位的CPU也只能存储区区32字节,存储能力真是小得可怜。
段寄存器 16位
P33ES----附加段寄存器extra segment
CS----代码段寄存器code segment
SS----栈段寄存器stack segment
DS----数据段寄存器data segment
FS----没有名称segment part2
GS----没有名称segment part3
MOV AL,[SI]
P34在汇编语言出现这个方括号,寄存器所代表的意义就变成了"内存"。对,内存就是指的插入式的内存条。
BYTE,WORD,DWORD
P35汇编语言的保留字,
MOV BYTE [678],123 因为内存和CPU没有什么数值概念,所以需要指定8个存储单元的。
MOV WORD [678],123 一共16位,0000000001111011,下位01111011保存在678号,上位00000000保存在旁边的679号。
内存地址的指定方法,不仅可以使用常数,还可以指定寄存器。
虽然可以用寄存器指定内存地址,但是可以这样做的寄存器是有限的,只有BX,BP,SI,DI这一个,
剩下的AX,CX,DX,SP不能用来指定内存地址。因为CPU没有处理这种指令的电路,或者说没有表示这种指令的机器
如果想把DX内存里的内容赋给AL的时候,就这样写:
MOV BX, DX
MOV AL,BYTE [BX]
ADD
P37加法指令,如果用C语言改写"ADD SI,1",就是SI=SI+1
CMP
P37比较指令,比如C语言中的if(a==3) {处理;} 对a和3比较时,将其翻译成机器语言时,必须先写"CMP a,3",告诉CPU比较对象,
然后下一步再写二者相等,需要做什么。
CMP A,0 将AL中的值和0进行比较
JE
P37条件跳转指令之一,所谓条件跳转指令,就是根据比较的结果决定跳转或不跳转。就JE指令而言,
如果比较结果相等,则跳转到指定的地址;如果不相等则不跳转,继续下一条指令。
CMP AL, 0
JE fin
相当于:if (AL == 0) {goto fin;}fin标号,结束之意。
INT
P37软件中断指令,以后会详讲
HLT
P39HLT是让CPU停止动作的指令,不过并不是彻底停止,而是让CPU进入待机状态。只要外部发生变化,比如按下键盘,移动鼠标,CPU就会醒过来,继续执行程序。
如果没有HLT指令,CPU就会不停的全力空转,这回使CPU的负荷达到100%,非常费电。我们仅仅加一个HLT指令,就可以让CPU基本处于睡眠状态,可以省很多的电。
源自英文"halt",意思是“停止”,halt也是Linux的一个关机命令。
制作启动分区
P40不要一下就用nask来做整个磁盘映像,而是先只用它来制作512字节的启动区,剩下的部分用磁盘映像管理工具来做,这样以后用起来就方便了。
Mafile 入门
P41-44
../z_tools/make.exe -r helloos.img
输入"make img"就能达到与"make -r helloos.img"一样的效果
-del ipl.bin
-del ipl.lst
删除掉最终成果(这里是helloos.img)以外的所有中间生成文件,把磁盘清理干净
../z_tools/make.exe clean
-del helloos.img
把源程序以外的文件全都删除干净。
../z_tools/make.exe img
默认动作,当执行不带参数的make时,相当于执行"make img"命令
Makefile
首先生成一个不带扩展名的Makefile#号
表示注释"ipl.bin : ipl.nas Makefile"
如果想要制作文件ipl.bin先检查一下ipl.nas和Makefile这2个文件是否准备好了。如果2个文件都有了,Make工具就会执行Makfile的下一行一行结束时的"\"
续行符号,表示这一行太长写不下去,跳转到下一行继续写。Makefile
可以自动从Makefile里寻找文件的生成方法,自动检查文件是不是最新img :
img :../z_tools/make.exe -r helloos.img
输入"make img"就能达到与"make -r helloos.img"一样的效果
clean :
clean :-del ipl.bin
-del ipl.lst
删除掉最终成果(这里是helloos.img)以外的所有中间生成文件,把磁盘清理干净
src_only :
src_only :../z_tools/make.exe clean
-del helloos.img
把源程序以外的文件全都删除干净。
default :
default :../z_tools/make.exe img
默认动作,当执行不带参数的make时,相当于执行"make img"命令
看来好的笔记风格有助于记录笔记的持久性,间接加强了学习^o^y