16位x86汇编求助:无法设置黄前景蓝背景显示
Hey there! As someone who’s tinkered with 16-bit x86 assembly in DOSBox back in the day, let’s break down what’s likely tripping you up here. Your issue with color not showing up (stuck on white-on-black) usually boils down to a few common missteps with text mode attributes, video mode setup, or how you’re outputting characters. Let’s dive in:
First, Let’s Clarify Text Mode Basics
In DOS’s standard 80x25 color text mode (mode 0x03), every on-screen character takes up 2 bytes in video memory (0xB8000):
- 1st byte: ASCII character code
- 2nd byte: Attribute byte (high 4 bits = background color, low 4 bits = foreground color)
- Blue background =
0x10, yellow foreground =0x0E→ combined attribute =0x1E
- Blue background =
Common Issues & Fixes
1. You might be setting the wrong video mode
If you accidentally switched to a graphics mode (like 0x13 for 320x200 256-color), text output works completely differently (pixel-by-pixel instead of character+attribute). Double-check your video mode setup code:
; Correct: Set 80x25 color text mode mov ah, 0x00 mov al, 0x03 ; This is the key—0x03 is standard color text int 0x10
2. Your clear-screen call is using default attributes
When you call the scroll/clear screen interrupt (int 0x10, function 0x06), the BH register defines the fill attribute. If you left BH as 0x07 (white-on-black), it’ll overwrite the entire screen with that color, even if you set attributes later. Fix it like this:
; Clear screen with yellow-on-blue (attribute 0x1E) mov ah, 0x06 mov al, 0x00 ; 0 = clear entire screen mov bh, 0x1E ; Blue background + yellow foreground mov ch, 0x00 ; Top-left row mov cl, 0x00 ; Top-left column mov dh, 0x18 ; Bottom-right row (24, since we start counting at 0) mov dl, 0x4F ; Bottom-right column (79) int 0x10
3. You’re not specifying attributes when outputting characters
If you’re using the teletype output function (int 0x10, function 0x0E), it uses the current attribute at the cursor position. If you didn’t set that attribute first, it’ll default to whatever was left from the clear screen or video mode setup. Instead, use function 0x09 to explicitly set the attribute for your text:
; Set cursor to (10,10) first mov ah, 0x02 mov bh, 0x00 ; Video page 0 mov dh, 0x0A ; Row 10 (0-indexed) mov dl, 0x0A ; Column 10 (0-indexed) int 0x10 ; Output a 'H' with yellow-on-blue attribute mov ah, 0x09 mov al, 'H' ; Character to print mov bh, 0x00 ; Video page mov bl, 0x1E ; Attribute (blue bg + yellow fg) mov cx, 0x01 ; Number of times to repeat the character int 0x10
4. Direct video memory writes are missing the attribute byte
If you’re writing directly to 0xB8000, make sure you’re writing 2 bytes (character + attribute), not just the character byte. For example:
; Write 'H' at top-left corner with yellow-on-blue mov word [0xB8000], 0x1E48 ; 0x1E = attribute, 0x48 = 'H'
If you only write mov byte [0xB8000], 'H', the attribute byte will stay as whatever was there before (probably white-on-black).
Full Working Example
Here’s a complete NASM .COM program that ties all this together:
org 0x100 ; DOS .COM program entry point section .text start: ; Set 80x25 color text mode mov ah, 0x00 mov al, 0x03 int 0x10 ; Clear screen with yellow-on-blue mov ah, 0x06 mov al, 0x00 mov bh, 0x1E mov ch, 0x00 mov cl, 0x00 mov dh, 0x18 mov dl, 0x4F int 0x10 ; Move cursor to center of screen mov ah, 0x02 mov bh, 0x00 mov dh, 0x0C ; Row 12 mov dl, 0x27 ; Column 39 int 0x10 ; Print "Hello, Assembly!" with yellow-on-blue mov ah, 0x09 mov al, 'H' mov bh, 0x00 mov bl, 0x1E mov cx, 0x01 int 0x10 ; Repeat for each character, or loop through a string—you get the idea ; Exit to DOS mov ah, 0x4C int 0x21
Quick Troubleshooting Checklist
- Did you confirm you’re using text mode
0x03(not a graphics mode)? - Is your clear-screen call setting
BHto0x1Einstead of0x07? - Are you explicitly specifying the attribute when printing characters (either via
int 0x10function0x09or full 2-byte writes to video memory)?
Give these fixes a shot—odds are one of them is the culprit. Let me know if you’re still stuck!
内容的提问来源于stack exchange,提问作者Erin Murphy

