You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

拆分独立引导加载程序后,自制汇编操作系统出现字符显示异常问题

拆分独立引导加载程序后,自制汇编操作系统出现字符显示异常问题

我刚给我的小型汇编操作系统实现了一个独立的引导加载程序,目前看起来能正常引导进入内核,但有个头疼的问题——字符显示不对。之前没拆分的时候(操作系统本身兼任引导加载程序)完全没这个问题,不过因为512字节的限制,不得不把引导和内核的功能分开来做。

这是拆分前后的显示效果对比(字符显示异常是拆分后新出现的情况)。

我除了调整引导签名(或者是不是必须保留这个签名?)和补全剩余空间为零的那行代码外,完全没修改内核的其他部分,实在摸不着头脑到底哪里出问题了……

我使用的内核代码:

MOV AX, 0     ; Set up segment registers
MOV DS, AX
MOV ES, AX
MOV SS, AX
MOV SP, 0x7C00

InputBufferSize equ 32  ; Set input buffer size

CALL PrintWelcomeMessage    ; Call function to print welcome message
CALL PrintCommandPrompt     ; Call function to print command prompt

JMP $         ; Loop forever

; Function to print welcome message
PrintWelcomeMessage:
MOV SI, WelcomeMessage     ; Load address of welcome message
PrintWelcomeLoop:
LODSB                      ; Load character from SI
OR AL, AL                  ; Check for null terminator
JZ WelcomeDone             ; If null terminator, we are done

MOV AH, 09                 ; Function 9 (Text color and attributes)
MOV BX, 001Fh              ; Set the text color
INT 10h

MOV AH, 0x0E               ; BIOS interrupt code for printing character
MOV BH, 0x00               ; Display page number
MOV BL, 0x07               ; Text attribute (white on black)
INT 0x10                   ; Call interrupt to print character

JMP PrintWelcomeLoop       ; Repeat for the next character
WelcomeDone:
JE NEWLINE
RET

; Function to print command prompt
PrintCommandPrompt:
MOV SI, CommandPrompt      ; Load address of command prompt
CALL PrintString           ; Call function to print string
JMP READ_INPUT             ; Jump to function to read user input

;THIS PART IS VERY IMPORTANT, IT WILL HANDLE COMMANDS;
; Function to handle user input
HANDLE_INPUT:
MOV DI, InputBuffer   ; Load address of input buffer
CMP BYTE [DI], 'h'    ; Check if input is 'h'
JNE NO_COMMAND       ; Jump to prompt if not "h"
CALL PrintHelp       ; Call function to print help information
JNE NEWLINE
JMP READ_INPUT       ; Jump back to prompt

PRINT_PROMPT:
JE NEWLINE
MOV SI, CommandPrompt ; Load address of command prompt
CALL PrintString      ; Call function to print command prompt
RET

NO_COMMAND:
MOV SI, CommandNotFound ; Load address of CommandNotFound
CALL PrintString
JMP PRINT_PROMPT
RET

VERSION_COMMAND:
MOV DI, InputBuffer   ; Load address of input buffer
CMP BYTE [DI], 'v'    ; Check if input is 'v'
JNE NO_COMMAND       ; Jump to prompt if not "v"
CALL PrintVersion       ; Call function to print Version information
JNE NEWLINE
JMP READ_INPUT       ; Jump back to prompt

PrintHelp:
MOV SI, HelpPrompt    ; Load address of help prompt
CALL PrintString      ; Call function to print help prompt
JMP PRINT_PROMPT      ; Jump back to prompt after printing help prompt
RET

PrintVersion:
MOV SI, Version    ; Load address of Version prompt
CALL PrintString      ; Call function to print Version prompt
JMP PRINT_PROMPT      ; Jump back to prompt after printing Version prompt
RET

; Function to read input from user
READ_INPUT:
MOV AH, 09                 ; Function 9 (Text color and attributes)
MOV BX, 00Fh               ; Set the text color
INT 10h

MOV AH, 0x00               ; BIOS interrupt code for reading character
INT 0x16                   ; Call interrupt to read character

CMP AL, 0x0D               ; Check for newline character
JE HANDLE_INPUT
JE NEWLINE                 ; If newline, print new line

CMP AL, 0x08               ; Check for backspace character
JE BACKSPACE

MOV [InputBuffer], AL      ; Store character in buffer
MOV SI, InputBuffer        ; Load address of input buffer
CALL PrintString           ; Call function to print user input

JMP READ_INPUT             ; Repeat until newline

READ_LOOP:
MOV AH, 0x00             ; BIOS interrupt code for reading character
INT 0x16                 ; Call interrupt to read character
CMP AL, 0x0D             ; Check for newline character
JE NEWLINE               ; If newline, print new line
MOV [DI], AL             ; Store character in buffer
INC DI                   ; Increment buffer pointer
INC CX                   ; Increment input length
CMP CX, InputBufferSize  ; Check if input buffer is full
JE READ_DONE             ; If buffer is full, exit loop
JMP READ_LOOP            ; Repeat until newline or buffer is full

NEWLINE:
MOV SI, NewLine            ; Load address of NewLine string
MOV AH, 0x0E               ; BIOS interrupt code for printing character
MOV BH, 0x00               ; Display page number
MOV BL, 0x07               ; Text attribute (white on black)
MOV AL, 0x0D               ; Carriage return character
INT 0x10                   ; Call interrupt to print carriage return
MOV AL, 0x0A               ; Newline character
INT 0x10                   ; Call interrupt to print newline
CALL PrintString
MOV SI, CommandPrompt      ; Load address of command prompt
CALL PrintString           ; Call function to print command prompt
JMP READ_INPUT             ; Repeat until newline or buffer is full

BACKSPACE:
CMP CL, 0                  ; No characters in the line?
JE READ_INPUT              ; Return to the read loop
DEC DI
MOV AH, 09                 ; Function 9 (Text color and attributes)
MOV BX, 0000               ; Set the text color
INT 10h
MOV BYTE [DI], 0           ; Delete the character
MOV AH, 0x0E
MOV AL, 0x08
INT 10h
MOV AL, ''
INT 10h
MOV AL, 0x08
INT 10h
JMP READ_INPUT

READ_DONE:
MOV BYTE [DI], 0x00           ; Add null terminator to input string
RET

; Function to print a null-terminated string
PrintString:
LODSB                      ; Load character from SI
OR AL, AL                  ; Check for null terminator
JZ PrintStringDone         ; If null terminator, return
MOV AH, 0x0E               ; BIOS interrupt code for printing character
MOV BH, 0x00               ; Display page number
MOV BL, 0x07               ; Text attribute (white on black)
INT 0x10                   ; Call interrupt to print character
JMP PrintString            ; Repeat until null terminator
PrintStringDone:
RET

;----Output messages----;
HelpPrompt DB ' List of commands: (add something)', 0
WelcomeMessage DB 'Welcome', 0
CommandPrompt DB 'Command: ', 0
CommandNotFound DB ' Non-Existing command', 0
Version DB 'Add version', 0

;----String constants----;
NewLine       DB 0x0D, 0x0A, 0
InputBufferSize equ 32                ; Set input buffer size
InputBuffer db InputBufferSize dup(0) ; Reserve space for input buffer

引导加载程序代码:

ORG 0x7C00
start:
xor ax, ax      ; Clear ax register
mov ss, ax      ; Set stack segment to 0
mov sp, 0x7C00  ; Set stack pointer to boot sector address

; Load the second-stage bootloader
mov ah, 0x02    ; BIOS read sector function
mov al, 1       ; Number of sectors to read
mov ch, 0       ; Cylinder number
mov dh, 0       ; Head number
mov bx, 0x1000  ; Address to load the second-stage bootloader
mov es, bx      ; Set es register to the segment of the destination address
xor bx, bx      ; Offset in es:bx set to 0
int 0x13        ; BIOS Interrupt to read HD

; Jump to the loaded program (OS)
jmp 0x1000:0000

times 510-($-$$) db 0  ; Fill with zeroes
dw 0xAA55              ; Boot signature

备注:内容来源于stack exchange,提问作者Luxo Luxo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 14:23:12