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

8086汇编VGA图形模式下动态输出average变量及分级提示需求

How to Display Dynamic Text & Conditional Messages in VGA Graphics Mode

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 font array (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 average is a 16-bit word, modify print_average to handle values up to 65535.

内容的提问来源于stack exchange,提问作者Tomer Cahal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 04:20:27