Windows下编写主引导程序到系统内核
?
Windows下编写主引导程序、系统内核程序都比在linux平台下麻烦得多。这里给一个例子:
?
K_CODE_SEG = 3000h K_CODE_OFFSET = 0000h _text segment org 7c00h _start: ; es, user data segment mov dx, K_CODE_SEG mov es, dx mov ah, 02h ;mov dl, 81h ; drive 0 驱动器 00H~7FH:软盘;80H~0FFH:硬盘 mov dl, 00h ;mov dl, 0 mov dh, 0 ; head 0 磁头 mov ch, 0 ; track 柱面 mov cl, 2 ; sector 扇区,读取第2个扇区 mov al, 10 ; 指定要读取的扇区数 mov bx, 0 ; 将指定扇区读到es:bx位置 int 13h jnc read_sector_ok read_sector_error: mov si, m_read_sector_error p1: mov al, [si] add si, 1 cmp al, 00h je endl mov ah, 0eh mov bx, 0fh int 10h jmp p1 read_sector_ok: mov si, m_read_sector_ok p0: mov al, [si] add si, 1 cmp al, 00h je jmp_to mov ah, 0eh mov bx, 0fh int 10h jmp p0 jmp_to: mov bx, 8 mov ax, es:[bx] mov dx, 16 mul dx mov cl, 4 shr ax, cl add ax, word ptr offset_segment_jmp_to + 2 mov word ptr offset_segment_jmp_to + 2, ax ; jmp 3000h:0h ;db 0eah ; jmp far ;dw K_CODE_OFFSET ; offset ;dw K_CODE_SEG ; segment: K_CODE_SEG = 3000h ; jmp 3000h:0h ;db 0eah ; jmp far ;dw K_CODE_OFFSET, K_CODE_SEG ; offset, segment. segment: K_CODE_SEG = 3000h ; jmp 3000h:0h offset_segment_jmp_to: dw K_CODE_OFFSET, K_CODE_SEG mov ax, cs cmp ax, K_CODE_SEG jz _1 jmp dword ptr offset_segment_jmp_to _1: jmp dword ptr offset_segment_jmp_to - 7c00h endl: hlt jmp endl m_read_sector_ok: db 0ah, 0ah db "[ook] read sector", 0dh, 0ah db 0ah, 0ah db 00h m_read_sector_error: db 0ah, 0ah db "[err] read sector", 0dh, 0ah db 0ah, 0ah db 00h ; MBR扇区位于整个硬盘的第一个扇区. ; 硬盘扇区为512字节,所以主引导程序大小仅能也只能512字节。 db 510-($-seg _start) dup(0) ; MBR结束标志 db 85, 170 ; 0x55, 0xaa _text ends end _start
?
.MODEL SMALL, C extrn test_09h:near _DATA SEGMENT MESSAGE1 DB '[1] HELLO, INT 21H->09H!', 0DH, 0AH, '$' _DATA ENDS _TEXT SEGMENT ASSUME CS:_TEXT, DS:_DATA ;ORG 1000H MAIN PROC NEAR _START: ; DS = DS + CS MOV AX, _DATA MOV DX, CS ADD AX, DX MOV DS, AX MOV SI, OFFSET MESSAGE1 PRINT_MESSAGE: MOV AL, [SI] CMP AL, '$' JE ENDL MOV AH, 0EH MOV BX, 0FH INT 10H INC SI JMP PRINT_MESSAGE ;MOV DX, OFFSET MESSAGE1 ; 字符串首偏移地址放到DX中 ;MOV AH, 9 ;INT 21H ; 输出字符串 ENDL: CALL test_09h ;EXIT: ; MOV AH, 4CH ; INT 21H EXIT: HLT JMP EXIT MAIN ENDP _TEXT ENDS END MAIN
?
char message[] = "Hello, MASM!\r\n$"; void test_09h() { _asm mov si, offset message; loop: _asm mov al, [si]; _asm cmp al, '$'; _asm je ret; _asm mov ah, 0eh; _asm mov bx, 0fh; _asm int 10h; _asm inc si; _asm jmp loop; ret: }
?
评论