8086汇编VGA图形模式下动态输出average变量及分级提示需求
Alright, since you already know how to switch to VGA graphics mode (I’ll assume you’re using mode 13h: 320x200 256-color, the most common one), let’s focus on rendering your dynamic average value and conditional messages. The key thing here is that you can’t use DOS’s INT 21h string functions in graphics mode—you have to draw each character pixel-by-pixel using the VGA video memory.
Here’s a complete, commented example in 8086 assembly that does exactly what you need:
Step 1: Define Your Data & Character Font
First, set up your data segment with the average variable, messages, and an 8x8 ASCII font (we’ll include only the characters we need to keep it concise):
DATASEG SEGMENT average DB 82 ; Example dynamic value, replace with your variable logic msg1 DB 'Your average is: ', 0 msg_good DB 'You are a good student, keep up the good work', 0 msg_improve DB 'Don''t worry you will get better!', 0 ; 8x8 ASCII font (partial: covers space, digits, required letters, punctuation) font DB 00h,00h,00h,00h,00h,00h,00h,00h ; Space (20h) DB 00h,00h,7Ch,82h,82h,7Ch,00h,00h ; 0 (30h) DB 00h,00h,84h,FEh,80h,00h,00h,00h ; 1 (31h) DB 00h,00h,82h,82h,FEh,80h,00h,00h ; 2 (32h) DB 00h,00h,82h,82h,FEh,82h,00h,00h ; 3 (33h) DB 00h,00h,8Eh,92h,FEh,80h,00h,00h ; 4 (34h) DB 00h,00h,FEh,80h,FEh,82h,00h,00h ; 5 (35h) DB 00h,00h,7Ch,80h,FEh,82h,00h,00h ; 6 (36h) DB 00h,00h,82h,82h,82h,FEh,00h,00h ; 7 (37h) DB 00h,00h,7Ch,82h,82h,7Ch,00h,00h ; 8 (38h) DB 00h,00h,7Ch,82h,82h,7Eh,00h,00h ; 9 (39h) DB 7Eh,81h,81h,81h,7Eh,00h,00h,00h ; Y (59h) DB 00h,7Dh,82h,82h,82h,7Dh,00h,00h ; o (6Fh) DB 00h,7Dh,82h,82h,82h,82h,00h,00h ; u (75h) DB 00h,7Fh,80h,80h,80h,7Fh,00h,00h ; r (72h) DB 00h,7Dh,82h,82h,82h,7Dh,00h,00h ; a (61h) DB 00h,FEh,10h,10h,10h,FEh,00h,00h ; v (76h) DB 00h,FEh,82h,82h,82h,82h,00h,00h ; e (65h) DB 00h,82h,FEh,80h,80h,00h,00h,00h ; i (69h) DB 00h,FEh,10h,28h,44h,FEh,00h,00h ; s (73h) DB 00h,00h,7Ch,00h,00h,7Ch,00h,00h ; : (3Ah) DB 00h,00h,00h,00h,00h,00h,00h,7Fh ; ! (21h) DATASEG ENDS
Step 2: Core Functions for Text Rendering
We’ll write two helper functions: one to print strings, and another to convert the average value to a decimal string and print it.
Function 1: Print a String to Graphics Mode
This function takes X/Y coordinates (in 8-pixel blocks), a color, and a string address, then draws each character using our font:
CODESEG SEGMENT ASSUME CS:CODESEG, DS:DATASEG print_string PROC ; Input: ; AH = Y coordinate (8-pixel row group) ; AL = X coordinate (8-pixel column group) ; BL = Color (0-255) ; SI = Address of null-terminated string pusha print_char_loop: mov dl, [si] ; Grab current character cmp dl, 0 ; Check for end of string je print_string_done ; Calculate font offset: (char - ASCII space) * 8 sub dl, 20h mov dh, 8 mul dh mov di, ax add di, offset font ; DI = pointer to character's 8x8 pixel data ; Calculate base video memory address for the current Y row group mov ax, ah mul 8 ; Convert row group to pixel Y mov dx, 320 mul dx ; AX = (pixel Y) * 320 (screen width) mov bx, ax ; BX = base address for this Y position mov cx, 8 ; Loop over 8 rows of the character char_row_loop: mov al, [di] ; Get current row's pixel pattern mov dx, cx ; Save row counter mov cx, 8 ; Loop over 8 columns of the row char_col_loop: rcl al, 1 ; Shift pixel bit into carry flag jnc skip_pixel ; Skip if bit is 0 (no pixel) ; Calculate exact pixel address in video memory mov ax, 7 sub ax, dx ; AX = row offset (0-7) mov cx, 320 mul cx ; AX = offset for row add ax, bx ; AX = base + row offset mov di, ax mov ax, al mul 8 ; Convert column group to pixel X add ax, 8 sub ax, cx ; AX = column offset (0-7) add di, ax mov [di], bl ; Draw pixel with selected color skip_pixel: loop char_col_loop inc di ; Move to next row in font data mov cx, dx ; Restore row counter loop char_row_loop inc si ; Next character in string inc al ; Shift X column right by 1 (8 pixels) jmp print_char_loop print_string_done: popa ret print_string ENDP
Function 2: Print the Numeric average Value
This converts the byte-sized average to a decimal string (max 3 digits: 0-255) and calls print_string:
print_average PROC ; Input: ; AH = Y coordinate (row group) ; AL = X coordinate (column group) ; BL = Color pusha mov al, average ; Load dynamic average value mov cx, 0 ; Digit counter mov bx, 10 ; Divisor for decimal conversion digit_loop: xor dx, dx div bx ; AX = quotient, DX = remainder (digit) add dl, 30h ; Convert remainder to ASCII digit push dx ; Save digit to stack (reverse order) inc cx cmp ax, 0 jne digit_loop ; Pop digits from stack to build correct-order string mov di, offset temp_str pop_digits: pop dx mov [di], dl inc di loop pop_digits mov [di], 0 ; Null-terminate the string ; Call print_string with the numeric string mov si, offset temp_str call print_string popa ret temp_str DB 4 DUP(0) ; Temporary storage for numeric string print_average ENDP
Step 3: Main Logic to Tie It All Together
Now switch to VGA mode, print the initial message, the average, then the conditional message:
main: mov ax, DATASEG mov ds, ax ; Switch to VGA 320x200 256-color mode (you already know this!) mov ax, 13h int 10h ; Print "Your average is:" at (X=5, Y=4) → 40px X, 32px Y mov ah, 4 ; Y row group mov al, 5 ; X column group mov bl, 15 ; White color mov si, offset msg1 call print_string ; Print average value right after the message (X=20, Y=4) mov ah, 4 mov al, 20 mov bl, 15 call print_average ; Check if average >75 and print corresponding message mov al, average cmp al, 75 jle print_improve_msg print_good_msg: mov ah, 7 ; Y row group (56px Y) mov al, 5 mov bl, 10 ; Green color mov si, offset msg_good call print_string jmp wait_key print_improve_msg: mov ah, 7 mov al, 5 mov bl, 12 ; Red color mov si, offset msg_improve call print_string wait_key: ; Wait for user key press to exit mov ah, 0 int 16h ; Switch back to text mode mov ax, 3h int 10h ; Exit program mov ah, 4Ch int 21h CODESEG ENDS END main
Quick Customization Tips
- Font Expansion: If you need more characters, add their 8x8 pixel patterns to the
fontarray (match ASCII order starting from space). - Positioning: Adjust the X/Y row groups (each group = 8 pixels) to move text anywhere on the screen.
- Colors: VGA mode 13h uses 0-255 colors—0 is black, 15 is white, 10 is green, 12 is red, etc.
- Larger Values: If
averageis a 16-bit word, modifyprint_averageto handle values up to 65535.
内容的提问来源于stack exchange,提问作者Tomer Cahal

