这里我们简单介绍一下Stage2.asm这个程序。
整个程序代码如下:
1: ; Note: Here, we are executed like a normal COM program, but we are still in
2: ; Ring 0. We will use this loader to set up 32 bit mode and basic exception
3: ; handling
4:
5: ; This loaded program will be our 32 bit kernal.
6:
7: ; We do not have the limitation of 512 bytes here, so we can add anything we
8: ; want here!
9:
10: org 0x0 ; offset to 0, we will set segments later
11: bits 16 ; we are still in real mode
12:
13: ; we are loaded at linear address 0x10000
14:
15: jmp main
16:
17: ;*********************************
18: ; Prints a String
19: ; DS=>SI: 0 terminated string
20: ;*********************************
21:
22: Print:
23: lodsb
24: or al, al
25: jz PrintDone
26: mov ah, 0eh
27: int 10h
28: jmp Print
29: PrintDone:
30: ret
31:
32: ;********************************
33: ; Second Stage Loader Entry Point
34: ;********************************
35:
36: main:
37: cli
38: push cs
39: pop ds
40: ; xor ax, ax ; org 0x0500
41: ; mov ds, ax ; org 0x0500
42:
43: mov si, Msg
44: call Print
45:
46: cli
47: hlt
48:
49: ;********************************
50: ; Data section
51: ;********************************
52:
53: Msg db "Preparing to load operating system...",13,10,0
这个程序非常简单,我们就不全部介绍了。只介绍第10行的这一句话。
由于我们在调用Print这个函数的时候,会使用DS:SI 来进行寻址,第10行把整个程序的偏移地址设为0,而在第38、39行重新设定了DS,所以不会产生问题(注意,Stage2.asm编译之后的二进制文件被加载到内存的0x0500处(即0x0050:0x0000))。
如果我们把第10行改成“org 0x0500”,那么就要在main函数中把DS设置为0,这样才能正确的打印出字符。