终于到了第二天。今天作者把程序部分也分解了,使用汇编代码把系统的运行过程展示出来。还借机介绍了寄存器, BIOS中断等。期间遇到的问题是资料太难找,我一般要有两份资料才能让我信服。。
寄存器:
我也先说一下寄存器。作者只介绍了8,16,32位寄存器,实际上还有64位寄存器。寄存器在汇编中几乎每行一个。wikipedia以前好像有一张图,现在不见了。还好我保存了。但是可以看到x86的。各个寄存器的用处,可以粗略的看一下Wikipedia,但是要详细的话还得看针对处理器的文档,比如abi,官方文档。
Memory Map:
知道一点寄存器的知识后,作者又引入了内存映射。就是说memory map。我找了很对地方也没有详细介绍内存映射的。总的来说就是0x00000000-0x00007BFF是bios用的,可以先不管。0x00007C00-0x00007DFF一共512bytes,是本次实验的重点。这是通常所说的boot sector(找不到更好的参考)中的数据载入的。其实这512bytes 也不能全是程序,大体结构如下所示。所以目前为止,写得都是bootloader,不是操作系统。。这些数据在磁盘上时是0-512bytes,为什么载入到内存就变成了0x00007C00-0x00007DFF,这就是ORG(origin)的作用。(The function of the ORG directive is to specify the origin address which NASM will assume the program begins at when it is loaded into memory。)
BIOS中断:
作者还介绍如何使用BIOS中断来显示字符。用的是0x10,第16号中断向量。关于BIOS中断的就比较多。还有说能改变字符颜色。我试了一下,不行。查了查说只有16位显示模式才行,我们的是256位显示模式。先不管。
程序主体:
下面是程序的主体部分,我使用nasm,所以有点不兼容,下面已经标出。我也趁机搞清楚了$和$$的区别。在nasm里,$代表这一行的(汇编之后)的位置,$$代表这个section的起点位置,如果只有.text那么$$=0。下面的程序只有.text,所以要确认的话可以加一个.data来测试一下($-$$)的值。总体程序见github。为什么这么写,可以见链接中的nasm参考。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | entry: MOV AX,0 ; Register initial: AX = 0 MOV SS,AX MOV SP,0x7c00 MOV DS,AX MOV ES,AX MOV SI,msg ; msg Address: 0x7c74 putloop: MOV AL,[SI] ; Get data in memory SI ADD SI,1 ; SI add 1 CMP AL,0 JE fin ; jump if equal MOV AH,0x0e ; display a char MOV BX,15 ; color INT 0x10 ; call BIOS video: interrupt 16th function JMP putloop fin: HLT ; halt cpu JMP fin ; msg: DB 0x0a, 0x0a ; new lines DB "NASM Success!!" DB 0x0a ; new line DB 0 RESB 0x1fe-($-$$) ; fill 0x00 only .text section, so $$ = 0 ;RESB 0x7dfe-($-$$) ; This is nask, nasm not support DB 0x55, 0xaa |
运行结果与上次一样就不截图了。
链接:
- GNU Memory map, BIOS Data Area, Memory Map
- Boot loader, Write Boot Sector Code, Grub
- StackOverflow, fifi, forum, pcasm, The Art Of Assembly Language
耗掉