环境:Ubuntu,nasm,bochs
asm 文件:
%include "common.inc" org 0x7c00 jmp LABEL_BEGIN [SECTION .gdt] LABEL_GDT: Descriptor 0, 0, 0 LABEL_DESC_CODE32 Descriptor 0, SegCode32Len -1, DA_C + DA_32 LABEL_DESC_VIDEO Descriptor 0xb8000, 0xffff, DA_DRW GdtLen equ $ - LABEL_GDT GdtPtr dw GdtLen - 1 dd 0 SelectorCode32 equ LABEL_DESC_CODE32 - LABEL_GDT SelectorVideo equ LABEL_DESC_VIDEO - LABEL_GDT [SECTION .s16] [BITS 16] LABEL_BEGIN: mov ax, cs mov ds, ax mov es, ax mov ss, ax mov sp, 0x100 xor eax, eax mov ax, cs shl eax, 4 add eax, LABEL_SEG_CODE32 mov word [LABEL_DESC_CODE32 + 2], ax shr eax, 16 mov byte [LABEL_DESC_CODE32 + 4], al mov byte [LABEL_DESC_CODE32 + 7], ah xor eax, eax mov ax, ds shl eax, 4 add eax, LABEL_GDT mov dword [GdtPtr + 2], eax lgdt [GdtPtr] cli in al, 0x92 or al, 00000010b out 92h, al mov eax, cr0 or eax, 1 mov cr0, eax jmp dword SelectorCode32:0 [SECTION .s32] [BITS 32] LABEL_SEG_CODE32: mov ax, SelectorVideo mov gs, ax xor ecx, ecx OutputMsgLoop: inc ecx xor ebx, ebx mov bx, word [Row] add bx, word [Line] add ebx, ecx add ebx, ecx mov edi, ebx mov ah, 0x0c mov al, byte[MsgBegin + ecx - 1] mov [gs:edi], ax cmp ecx, MsgEnd - MsgBegin jnz OutputMsgLoop jmp $ MsgBegin: db "Hello World from Proteas" MsgEnd: Row dw 80 * 11 * 2 Line dw (79 - (MsgEnd - MsgBegin)) * 2 SegCode32Len equ $ - LABEL_SEG_CODE32
inc 文件:
DA_32 EQU 4000h;0100 0000 0000 0000 DA_DPL0 EQU 00h DA_DPL1 EQU 20h DA_DPL2 EQU 40h DA_DPL3 EQU 60h DA_DR EQU 90h DA_DRW EQU 92h DA_DRWA EQU 93h DA_C EQU 98h DA_CR EQU 9Ah DA_CCO EQU 9Ch DA_CCOR EQU 9Eh DA_LDT EQU 82h DA_TaskGate EQU 85h DA_386TSS EQU 89h DA_386CGate EQU 8Ch DA_386IGate EQU 8Eh DA_386TGate EQU 8Fh SA_RPL0 EQU 0 SA_RPL1 EQU 1 SA_RPL2 EQU 2 SA_RPL3 EQU 3 SA_TIG EQU 0 SA_TIL EQU 4 ; usage: Descriptor Base, Limit, Attr ; Base: dd ; Limit: dd (low 20 bits available) ; Attr: dw (lower 4 bits of higher byte are always 0) %macro Descriptor 3 dw %2 & 0FFFFh ; 段界限1 dw %1 & 0FFFFh ; 段基址1 db (%1 >> 16) & 0FFh ; 段基址2 dw ((%2 >> 8) & 0F00h) | (%3 & 0F0FFh) ; 属性1 + 段界限2 + 属性2 db (%1 >> 24) & 0FFh ; 段基址3 %endmacro ; 共 8 字节 ; usage: Gate Selector, Offset, DCount, Attr ; Selector: dw ; Offset: dd ; DCount: db ; Attr: db %macro Gate 4 dw (%2 & 0FFFFh) ; 偏移1 dw %1 ; 选择子 dw (%3 & 1Fh) | ((%4 << 8) & 0FF00h) ; 属性 dw ((%2 >> 16) & 0FFFFh) ; 偏移2 %endmacro ; 共 8 字节
make 文件:
boot.bin:boot.asm Makefile nasm -o ./bin/boot.bin boot.asm clean: rm -rf ./bin/boot.bin img: dd if=./bin/boot.bin of=./bin/vdisk.img bs=512 count=1 conv=notrunc
经验与教训:在代码段中插入数据,要放入代码段的底部,否则会被当做指令执行。