《30天》的汇编实现(二)

来源:互联网 发布:电影制作软件下载 编辑:程序博客网 时间:2024/05/29 10:26
第3天
目标:1、让主引导程序读也软盘的20个柱面的数据     ip110.asm
           2、设置一些系统用到的参数                              asmhead.asm
           3、跳转到保护模式                                            bootpack.asm


一、软盘逻辑扇区从0开始编号,每扇区占512字节。20柱面的数据都读取到8000H开始的内存中。
软盘中有一些有特定作用的扇区:
0号扇区MBR,也叫主引导扇区,被BIOS自动读取到7C00H处
1~9号扇区FAT1、10~18号扇区FAT2,FAT系列的文件系统都有2个一模一样的FAT
19~32号扇区根目录区,它限制了根目录可以有多少个条目
从33号扇区开始就是数据区,很长一段时间,软盘中只有一个文件asmhead.com,这样此文件在数据区中就是连续的,如果有多个文件,而asmhead.com需要增减数据,就会出现数据不连续的情况,这种情况的处理,现在不讨论。
asmhead.com在软盘中的地址是33号扇区,当20柱面被读入8000H时,asmhead.com在内存中的地址就是0C200H,所以MBR最后会跳转到0C200H执行。
二、设置显示模式,保存显示模式对应的参数,保存键盘标志,打开A20地址线,加载全局描述符
虽然我在代码中写的是“跳转到保护模式”,其实CS寄存器并没有工作在保护模式下
但是其它的段寄存器是工作在保护模式下的(只能算半保护模式吧),这样程序就可以访问1M以上的内存了
把8000H开始的20柱面的数据复制到100000H处,把完全保护模式下的代码(bootpack.com)复制到280000H处,
设置栈顶为310000H,跳转到bootpack.com并转入完全保护模式。
bootpack.asm编译成功后,用incbin嵌入asmhead.com的后面
三、这时候已经进入完全保护模式,所有的段寄存器的高速缓存都刷新了。
在原书中,这是C语言的领域了,在第3天,只有一个代码hlt






下面分享一下我的得意之作:宏定义
在bootpack.inc中,我定义有几个宏用于程序控制
比如说如果eax小于0则ecx清0
if eax,l,0
xor ecx,ecx
endif
当然还有else和elseif
第2个参数是用条件跳转指令中的字母表示的:
a、b、ae、be分别表示无符号的大于、小于、大于等于、小于等于
g、l、ge、le分别表示有符号的大于、小于、大于等于、小于等于
三个参数是通过第1参数和第3参数的cmp得到的,也可以用1个参数,通过判断标志位来实现
比如:
test eax,eax
if z
xor ecx,ecx
endif


循环结构是repeat until 和while  endw
比如1到100的累加:
xor eax,eax
mov ecx,1
while ecx,be,100
add eax,ecx
inc ecx
endw
或者
xor eax,eax
mov ecx,1
repeat
add eax,ecx
inc ecx
until ecx,a,100




最后是invoke子程序调用宏:
这个和masm差不多,第1个参数是子程序名,其它是参数
如果是字符串参数,则要在宏定义中更改数据段及代码段的段名
如果是立即数入栈,直接作为参数即可
如果是变量入栈,要有byte、word、dword的修饰
如果是直接地址入栈,与立即数入栈是一样的
如果是变量地址入栈,要有addr修饰
比如:invoke sprintf,dword [.s],"memory %dMB     free :%dKB",edx,eax
扩展开就是:
push eax
push edx
[section .data]
%%msg db "memory %dMB     free :%dKB",0
[section .code]
push %%msg
push dword [.s]
call sprintf


嗯,就说到这里吧,表达水平有限,大家可以下载相应的代码


云盘地址:http://pan.baidu.com/s/1pL5YPhL

0 0
原创粉丝点击