进入第三章的学习~第三章开始每章内容变多了,所以以后每学习一节写一篇文章~
顺便注一句:书上“用来生成描述符的宏”只是节自光盘中的pm.inc文件的,我照书上敲了那短短一段发现编译的时候报错- -不过我相信大家的眼睛都比我雪亮
因为引导扇区空间只有512个字节,解决这个问题有俩办法:自己写一个引导扇区or借用别人的引导扇区(从作者的话看起来以后会涉及自己写引导扇区~期待),咱用第二种,借用一下别人的扇区。又要去Bochs官网下东西了(还是进不去。。),幸亏有好心人~freedos-img下载,把其中的a.img复制到目录中,改名为freedos.img。用第二章的方法再生成一个叫做pm.img的软盘映像(bximage命令,然后fd -> 1.44 -> pm.img),也放到目录中。然后修改bochsrc文件,把原先的floppy:…与boot: …删掉,换成下面三行:
floppya: 1_44=freedos.img, status=inserted
floppyb: 1_44=pm.img, status=inserted
boot: a
启动Bochs,会发现界面显示出A:\>,这时我们输入format b:,会提示Format operation complete.(这时不用关Bochs)
在pmtest1.asm中将org后面的07c00h改为0100h,重新编译(注意,这里编译成.com):
nasm pmtest1.asm -o pmtest1.com
将pmtest1.com复制到虚拟软盘pm.img上:
sudo mount -o loop pm.img /mnt/floppy(如果没有此目录,则要先mkdir /mnt/floppy,不然会报“挂载点/mnt/floppy不存在”)
sudo cp pmtest1.com /mnt/floppy/
sudo umount /mnt/floppy
如果成功的话,在Bochs中输入dir b:会出现Directory of B:\*.*,下面还有几行,如果不成功,会出现File not found.这说明pmtest1.com复制失败(有可能是因为关了Bochs)
然后在Bochs中执行b:\pmtest1.com,会发现红色的P出现在了屏幕最右端~
以上为代码操作部分,下面是理论部分——
“Intel 8086是16位的CPU,有16位的寄存器、16位数据总线、20位地址总线,1MB寻址能力。”
物理地址 = 段值 * 16 + 偏移 (其中段值和偏移均为16位)
实模式和保护模式中的段的概念有着根本区别。实模式下,段值可看作是地址的一部分(比如说段值为XXXXh表示以XXXX0h开始的一段内存)。但是保护模式下,段只是一个索引,指向GDT(即global descriptor table,全局描述符表)的一个表项(描述符)。描述符详细定义了段的起始地址、界限、属性等内容。GDT的作用是提供段式存储机制(此机制通过段寄存器和GDT中的描述符共同提供)
一个讲GDT描述符的文章见这里(其中涉及到“一致码段”,下面有表列出一致与非一致的比较),还有这篇文章讲的很好:保护模式下如何寻址
SelectorVideo equ LABEL_DESC_VIDEO - LABEL_GDT
在别的地方看到这样一句话:“选择子确定描述符,描述符确定段基地址,段基地址与偏移之和就是线性地址。”
“段:偏移”形式的逻辑地址经过段机制转化成线性地址,而不是物理地址。不过暂时在这里线性地址就是物理地址。
关于A20地址线:8086->80286寻址范围扩大,但是8086只能寻到1MB,如果访问超过1MB的地址,虽然不会发生异常,但是又从0开始寻址,所以为了保证兼容,使用8042键盘控制器来控制第20个地址(从0开始数)。所以为了访问所有内存,需要把A20打开,默认是关闭的。
寄存器cr0的第0位是PE位,此位为0时是实模式,为1时是保护模式。
jmp dword SelectorCode32:0
特权级 低->高 |
特权级 高->低 |
相同特权 级之间 |
适用于何种代码 | |
---|---|---|---|---|
一致代码段 | Yes | No | Yes | 不访问受保护的资源和某些类型 的异常处理的系统代码 |
非一致代码段 | No | No | Yes | 避免低特权级的程序访问而被 保护起来的系统代码 |
数据段(总是非一致) | No | Yes | Yes |
几个指令的含义:
equ——相当于赋值,可以将一个数值或者一个寄存器名赋给一个指定的符号名。
[gs:edi]——段寄存器名:段名,在这里即代表段:偏移
lgdt——可以把GDT描述符表的大小和起始地址存入gdt寄存器中