打印"hello,world!":
1 ; hello-os 2 ; TAB=4 3 4 ORG 0x7c00 ; 将代码装载到内存0x7c00处 5 6 ; 以下是标准FAT12软盘专用代码 7 8 JMP entry 9 DB 0x90 10 DB "HELLOOS" ; 启动区名称(任意字符串,长度必须为8字节) 11 DW 512 ; 每个扇区的大小(必须为512) 12 DB 1 ; 簇的大小(必须为1) 13 DW 1 ; FAT的起始位置(一般从第一扇区开始) 14 DB 2 ; FAT的个数(必须为2) 15 DW 224 ; 根目录的大小(一般设置成如此即可) 16 DW 2880 ; 磁盘大小(必须为2880) 17 DB 0xf0 ; 磁盘的种类(必须为0xf0) 18 DW 9 ; FAT的长度(必须是9扇区) 19 DW 18 ; 1个磁道的所包含的扇区数(必须为18) 20 DW 2 ; 磁头数(必须为2) 21 DD 0 ; 不使用分区,必须是0 22 DD 2880 ; 重写磁盘大小 23 DB 0,0,0x29 ; 意义不明,固定 24 DD 0xffffffff ; 可能是卷标号码 25 DB "HELLO-OS " ; 磁盘名(11字节) 26 DB "FAT12 " ; 磁盘格式(8字节) 27 RESB 18 ; 空出18字节 28 29 ; 程序核心 30 31 entry: 32 MOV AX,0 ; 初始化寄存器 33 MOV SS,AX 34 MOV SP,0x7c00 35 MOV DS,AX 36 MOV ES,AX 37 38 MOV SI,msg 39 putloop: 40 MOV AL,[SI] 41 ADD SI,1 ; 给SI加1 42 CMP AL,0 43 JE fin 44 MOV AH,0x0e ; 显示一个文字 45 MOV BX,15 ; 选定字符颜色 46 INT 0x10 ; 调用显卡BIOS 47 JMP putloop 48 fin: 49 HLT ; 使CPU停止 50 JMP fin ; 无限循环 51 52 msg: 53 DB 0x0a, 0x0a ; 两次换行 54 DB "hello, world" 55 DB 0x0a ; 再次换行 56 DB 0 57 58 RESB 0x7dfe-$ ; 填充剩余字节 59 60 DB 0x55, 0xaa
(注:启动区内容的装载地址为,0x00007c00至0x00007dff)
真正的IPL:
1 ; haribote-ipl 2 ; TAB=4 3 4 CYLS EQU 10 5 6 ORG 0x7c00 7 8 9 10 JMP entry 11 DB 0x90 12 DB "HARIBOTE" 13 DW 512 14 DB 1 15 DW 1 16 DB 2 17 DW 224 18 DW 2880 19 DB 0xf0 20 DW 9 21 DW 18 22 DW 2 23 DD 0 24 DD 2880 25 DB 0,0,0x29 26 DD 0xffffffff 27 DB "HARIBOTEOS " 28 DB "FAT12 " 29 RESB 18 30 31 32 33 entry: 34 MOV AX,0 35 MOV SS,AX 36 MOV SP,0x7c00 37 MOV DS,AX 38 39 40 MOV AX,0x0820 41 MOV ES,AX 42 MOV CH,0 43 MOV DH,0 44 MOV CL,2 45 readloop: 46 MOV SI,0 47 retry: 48 MOV AH,0x02 49 MOV AL,1 50 MOV BX,0 51 MOV DL,0x00 52 INT 0x13 53 JNC next 54 ADD SI,1 55 CMP SI,5 56 JAE error 57 MOV AH,0x00 58 MOV DL,0x00 59 INT 0x13 60 JMP retry 61 next: 62 MOV AX,ES 63 ADD AX,0x0020 64 MOV ES,AX 65 ADD CL,1 66 CMP CL,18 67 JBE readloop 68 MOV CL,1 69 ADD DH,1 70 CMP DH,2 71 JB readloop 72 MOV DH,0 73 ADD CH,1 74 CMP CH,CYLS 75 JB readloop 76 77 78 79 MOV [0x0ff0],CH 80 JMP 0xc200 81 82 error: 83 MOV SI,msg 84 putloop: 85 MOV AL,[SI] 86 ADD SI,1 87 CMP AL,0 88 JE fin 89 MOV AH,0x0e 90 MOV BX,15 91 INT 0x10 92 JMP putloop 93 fin: 94 HLT 95 JMP fin 96 msg: 97 DB 0x0a, 0x0a 98 DB "load error" 99 DB 0x0a 100 DB 0 101 102 RESB 0x7dfe-$ 103 104 DB 0x55, 0xaa
导入C语言:
1 void io_hlt(void); 2 3 void HariMain(void) 4 { 5 fin: 6 io_hlt(); 7 goto fin; 8 }
本书作者为大家配备的函数库(汇编):
BOTPAK EQU 0x00280000 DSKCAC EQU 0x00100000 DSKCAC0 EQU 0x00008000 CYLS EQU 0x0ff0 LEDS EQU 0x0ff1 VMODE EQU 0x0ff2 SCRNX EQU 0x0ff4 SCRNY EQU 0x0ff6 VRAM EQU 0x0ff8 ORG 0xc200 MOV AL,0x13 MOV AH,0x00 INT 0x10 MOV BYTE [VMODE],8 MOV WORD [SCRNX],320 MOV WORD [SCRNY],200 MOV DWORD [VRAM],0x000a0000 MOV AH,0x02 INT 0x16 MOV [LEDS],AL MOV AL,0xff OUT 0x21,AL NOP OUT 0xa1,AL CLI CALL waitkbdout MOV AL,0xd1 OUT 0x64,AL CALL waitkbdout MOV AL,0xdf OUT 0x60,AL CALL waitkbdout [INSTRSET "i486p"] LGDT [GDTR0] MOV EAX,CR0 AND EAX,0x7fffffff OR EAX,0x00000001 MOV CR0,EAX JMP pipelineflush pipelineflush: MOV AX,1*8 MOV DS,AX MOV ES,AX MOV FS,AX MOV GS,AX MOV SS,AX MOV ESI,bootpack MOV EDI,BOTPAK MOV ECX,512*1024/4 CALL memcpy MOV ESI,0x7c00 MOV EDI,DSKCAC MOV ECX,512/4 CALL memcpy MOV ESI,DSKCAC0+512 MOV EDI,DSKCAC+512 MOV ECX,0 MOV CL,BYTE [CYLS] IMUL ECX,512*18*2/4 SUB ECX,512/4 CALL memcpy MOV EBX,BOTPAK MOV ECX,[EBX+16] ADD ECX,3 SHR ECX,2 JZ skip MOV ESI,[EBX+20] ADD ESI,EBX MOV EDI,[EBX+12] CALL memcpy skip: MOV ESP,[EBX+12] JMP DWORD 2*8:0x0000001b waitkbdout: IN AL,0x64 AND AL,0x02 JNZ waitkbdout RET memcpy: MOV EAX,[ESI] ADD ESI,4 MOV [EDI],EAX ADD EDI,4 SUB ECX,1 JNZ memcpy RET ALIGNB 16 GDT0: RESB 8 DW 0xffff,0x0000,0x9200,0x00cf DW 0xffff,0x0000,0x9a28,0x0047 DW 0 GDTR0: DW 8*3-1 DD GDT0 ALIGNB 16 bootpack:
导入C语言需要的函数:
[FORMAT "WCOFF"] [BITS 32] [FILE "naskfunc.nas"] GLOBAL _io_hlt [SECTION .text] _io_hlt: HLT RET