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

QEMU中汇编OS代码设置文本红色无效的解决方法

引导加载器文本颜色设置问题解决

问题说明

尝试在16位BIOS引导加载器中,通过在字符串里插入0x04(对应红色)作为颜色控制字符,实现部分文本红色显示,但运行qemu-system-x86_64 -fda C:\Users\Ukraine\Documents\CyberOS\boot.bin后颜色未生效。

原始核心代码片段:

hello db 'CyberOS terminal edition', 0x04, 'version 0.1a', 0x0A, 'created by SomeOne_GuY',  0 ;вивести на екран

print_string:
    mov ah, 0x0E ;Значення яке оброблює переривання, щоб зробити значення з усіх та вивести на екран
.repeat_next_char:
    lodsb ;завантажуємо перший символ з того hello: символ "C"
    cmp al, 0
    je .done_print
    int 0x10    ;переривання відео виклику BIOS
    jmp .repeat_next_char

问题原因

BIOS的INT 0x10 AH=0x0E(电传打字机输出模式)仅负责输出ASCII字符,不会自动解析颜色控制码。要改变文本颜色,必须通过修改寄存器BL(文本属性)来实现:

  • BL低4位:前景色(0=黑,4=红,7=白等)
  • BL高4位:背景色(0=黑,4=红等)

解决方案

方案1:在打印函数中识别控制码切换颜色

修改print_string函数,让它检测到颜色控制字符时,更新BL寄存器的属性值:

[bits 16]       
[org 0x7c00]    

start:
    xor ax, ax
    mov ds, ax
    mov es, ax
    
    ; 初始化彩色文本模式(确保颜色属性生效)
    mov ah, 0x00
    mov al, 0x03 ; 80x25彩色文本模式
    int 0x10
    
    mov si, hello
    call print_string
    
    jmp $ ; 无限循环,避免执行后续数据

hello db 'CyberOS terminal edition', 0x04, 'version 0.1a', 0x0A, 'created by SomeOne_GuY', 0

print_string:
    mov ah, 0x0E
    mov bh, 0x00 ; 视频页号固定为0
    mov bl, 0x07 ; 默认属性:白字黑底
.repeat_next_char:
    lodsb
    cmp al, 0
    je .done_print
    
    ; 检测颜色控制码0x04,切换为红字黑底
    cmp al, 0x04
    je .set_red_color
    
    ; 输出当前字符
    int 0x10
    jmp .repeat_next_char
.set_red_color:
    mov bl, 0x04 ; 设置前景色为红色
    jmp .repeat_next_char
.done_print:
    ret

times (510 -($-$$)) db 0x00
dw 0xAA55

方案2:拆分字符串分别设置颜色

把不同颜色的文本拆分为独立字符串,调用带颜色参数的打印函数:

[bits 16]       
[org 0x7c00]    

start:
    xor ax, ax
    mov ds, ax
    mov es, ax
    
    mov ah, 0x00
    mov al, 0x03
    int 0x10
    
    ; 输出第一部分(默认白字)
    mov si, hello_part1
    mov bl, 0x07
    call print_string_with_color
    
    ; 输出第二部分(红字)
    mov si, hello_part2
    mov bl, 0x04
    call print_string_with_color
    
    ; 输出第三部分(默认白字)
    mov si, hello_part3
    mov bl, 0x07
    call print_string_with_color
    
    jmp $

hello_part1 db 'CyberOS terminal edition', 0
hello_part2 db 'version 0.1a', 0x0A, 0
hello_part3 db 'created by SomeOne_GuY', 0

print_string_with_color:
    mov ah, 0x0E
    mov bh, 0x00
.repeat_next_char:
    lodsb
    cmp al, 0
    je .done_print
    int 0x10
    jmp .repeat_next_char
.done_print:
    ret

times (510 -($-$$)) db 0x00
dw 0xAA55

关键注意点

  1. 必须先初始化视频模式为0x03(彩色文本模式),否则颜色属性可能不生效
  2. 添加jmp $无限循环,防止CPU执行到字符串变量的字节(把数据当指令执行会导致错误)
  3. BL的属性值可以自由组合,比如0x47是白字红底,0x0C是亮红字黑底

内容的提问来源于stack exchange,提问作者Dmytro Parkhomenko

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 15:29:57