Environment: Ubuntu, nasm, bochs
Asm file:
% Include "common. inc "<br/> org 0x7c00 <br/> jmp LABEL_BEGIN <br/> [SECTION. gdt] <br/> LABEL_GDT: Descriptor 0, 0, 0 <br/> LABEL_DESC_CODE32Descriptor 0, SegCode32Len-1, DA_C + DA_32 <br/> 0xb8000, 0 xffff, DA_DRW <br/> GdtLen equ $-LABEL_GDT <br/> GdtPtr dw GdtLen-1 <br/> dd 0 <br/> SelectorCode32 equ accept-LABEL_GDT <br/> SelectorVideo equ LABEL_DESC_VIDEO-LABEL_GDT <br/> [SECTION. s16] <br/> [BITS 16] <br/> LABEL_BEGIN: <br/> mov ax, cs <br/> mov ds, ax <br/> mov es, ax <br/> mov ss, ax <br/> mov sp, 0x100 <br/> xor eax, eax <br/> mov ax, cs <br/> shl eax, 4 <br/> add eax, LABEL_SEG_CODE32 <br/> mov word [LABEL_DESC_CODE32 + 2], ax <br/> shr eax, 16 <br/> mov byte [LABEL_DESC_CODE32 + 4], al <br/> mov byte [LABEL_DESC_CODE32 + 7], ah <br/> xor eax, eax <br/> mov ax, ds <br/> shl eax, 4 <br/> add eax, LABEL_GDT <br/> mov dword [GdtPtr + 2], eax <br/> lgdt [GdtPtr] <br/> cli <br/> in al, 0x92 <br/> or al, 00000010b <br/> out 92 h, al <br/> mov eax, cr0 <br/> or eax, 1 <br/> mov cr0, eax <br/> jmp dword SelectorCode32: 0 <br/> [SECTION. s32] <br/> [BITS 32] <br/> LABEL_SEG_CODE32: <br/> mov ax, SelectorVideo <br/> mov gs, ax </p> <p> xor ecx, ecx <br/> OutputMsgLoop: <br/> inc ecx </p> <p> xor ebx, ebx <br/> mov bx, word [Row] <br/> add bx, word [Line] <br/> add ebx, ecx <br/> add ebx, ecx </p> <p> mov edi, ebx <br/> mov ah, 0x0c <br/> mov al, byte [MsgBegin + ecx-1] <br/> mov [gs: edi], ax <br/> cmp ecx, msgEnd-MsgBegin <br/> jnz OutputMsgLoop </p> <p> jmp $ </p> <p> MsgBegin: db "Hello World from Proteas" <br/> MsgEnd: <br/> Row dw 80*11*2 <br/> Line dw (79-(MsgEnd-MsgBegin) * 2 <br/> SegCode32Len equ $-LABEL_SEG_CODE32
Inc file:
DA_32EQU4000h; 0100 0000 0000 0000 <br/> latency <br/> DA_DPL3EQU60h <br/> DA_DREQU90h <br/> DA_DRWEQU92h <br/> DA_DRWAEQU93h <br/> DA_CEQU98h <br/> DA_CREQU9Ah <br/> DA_CCOEQU9Ch <br/> DA_CCOREQU9Eh <br/> latency <br/> DA_386TSSEQU89h <br/> latency <br/> Issue <br/> SA_RPL0EQU0 <br/> Issue <br/> SA_RPL2EQU2 <br/> SA_RPL3EQU3 <br/> SA_TIGEQU0 <br/> SA_TILEQU4 <br/>; usage: Descriptor Base, Limit, Attr <br/>; Base: dd <br/>; Limit: dd (low 20 bits available) <br/>; Attr: dw (lower 4 bits of higher byte are always 0) <br/> % macro Descriptor 3 <br/> dw % 2 & 0 FFFFh; segment limit 1 <br/> dw % 1 & 0 FFFFh; Segment Base Address 1 <br/> db (% 1> 16) & 0FFh; segment Base Address 2 <br/> dw (% 2> 8) & 0F00h) | (% 3 & 0F0FFh ); attribute 1 + segment limit 2 + attribute 2 <br/> db (% 1> 24) & 0FFh; Segment Base Address 3 <br/> % endmacro; 8 bytes in total <br/>; usage: Gate Selector, Offset, DCount, Attr <br/>; Selector: dw <br/>; Offset: dd <br/>; DCount: db <br/>; Attr: db <br/> % macro Gate 4 <br/> dw (% 2 & 0 FFFFh ); offset 1 <br/> dw % 1; Select Sub <br/> dw (% 3 & 1Fh) | (% 4 <8) & 0FF00h ); attribute <br/> dw (% 2> 16) & 0 FFFFh); offset 2 <br/> % endmacro; 8 bytes in total
Make file:
Boot. bin: boot. asm Makefile <br/> nasm-o. /bin/boot. bin boot. asm <br/> clean: <br/> rm-rf. /bin/boot. bin <br/> img: <br/> dd if =. /bin/boot. bin of =. /bin/vdisk. img bs = 512 count = 1 conv = notrunc
Experience and Lessons: insert data into a code segment and put it at the bottom of the code segment. Otherwise, it will be executed as a command.