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

MASM编程求助:用ah=02h int21h实现闪烁反显多行文本

问题描述

基于MASM编写汇编程序,要求使用ah=02h int 21h实现文本显示,且文本需具备闪烁+反显的高亮效果。具体需求如下:

  1. 先清空屏幕背景;
  2. 显示message1,样式为黑字白背景+闪烁高亮;
  3. 光标上移两行后显示message2,样式同上;
  4. 光标再上移两行后显示message3,样式同上。

任务明确要求使用int 21h的ah=02h功能输出文本,但未禁止使用其他DOS/BIOS功能辅助实现。

以下是我已编写的部分代码:

stack   segment para stack 'stack'  ; 栈段定义
    db 64 dup('stack***')            
stack   ends                        
 
dseg    segment para public 'data'  ; 数据段定义
    message1 db 'This is line 1:$'
    message2 db 'This is line 2'
    message3 db 'This is line 3'  
    Cls             db      1Bh, '[2J', '$'
    cl1  db  '7m'
dseg ends                           
 
cseg    segment para public 'code'  ; 代码段定义
prog proc far                      
    assume cs:cseg, ds:dseg, ss:stack 
    
    mov ax, dseg                   
    mov ds, ax                       
    mov  ax,1003h
    mov  bl,112
    int 10h
    
    lea dx,message1
    mov ah, 09h
    int 21h
 
    ; 程序结束
    mov ah, 4Ch                   
    int 21h                       
prog  endp ; 结束主程序过程
cseg  ends ; 结束代码段
         end prog ; 程序入口

现在需要帮助完成整个程序的编写。


完整实现代码

以下是满足需求的完整MASM代码,核心用int 21h ah=02h输出字符,通过BIOS功能设置显示属性和光标位置:

stack   segment para stack 'stack'
    db 64 dup('stack***')            
stack   ends                        
 
dseg    segment para public 'data'
    ; 定义三条消息,以0作为结束标记(用于逐个字符遍历)
    message1 db 'This is line 1', 0
    message2 db 'This is line 2', 0
    message3 db 'This is line 3', 0
    ; ANSI清屏序列
    cls_seq db 1Bh, '[2J', '$'
dseg ends                           
 
cseg    segment para public 'code'
prog proc far                      
    assume cs:cseg, ds:dseg, ss:stack 
    
    ; 初始化数据段
    mov ax, dseg                   
    mov ds, ax                       

    ; 第一步:清屏
    lea dx, cls_seq
    mov ah, 09h
    int 21h

    ; 设置80x25文本模式,启用闪烁支持
    mov ax, 0003h
    int 10h

    ; 定位初始光标到第23行(从0计数)、第10列
    mov ah, 02h
    mov bh, 00h   ; 显示页号为0
    mov dh, 23    ; 行号
    mov dl, 10    ; 列号
    int 10h

    ; 显示message1
    lea si, message1
    call print_with_attr

    ; 光标上移两行
    mov ah, 03h   ; 获取当前光标位置
    int 10h
    sub dh, 2     ; 行号减2
    mov ah, 02h   ; 设置新光标位置
    int 10h

    ; 显示message2
    lea si, message2
    call print_with_attr

    ; 光标再上移两行
    mov ah, 03h
    int 10h
    sub dh, 2
    mov ah, 02h
    int 10h

    ; 显示message3
    lea si, message3
    call print_with_attr

    ; 等待按键,方便查看结果
    mov ah, 07h
    int 21h

    ; 程序退出
    mov ah, 4Ch                   
    int 21h                       

; 子程序:逐个输出SI指向的字符串,每个字符带闪烁+反显属性
print_with_attr proc near
    push ax
    push bx
    push cx
    push dx

print_loop:
    mov al, [si]
    cmp al, 0
    je print_exit  ; 遇到结束符则退出

    ; 设置字符属性:闪烁(最高位1)+ 白背景(位6-4=111)+ 黑前景(位3-0=000)
    mov ah, 09h
    mov bh, 00h
    mov bl, 0F0h
    mov cx, 1      ; 仅应用到当前字符
    int 10h

    ; 用int21h ah=02h输出字符
    mov dl, al
    mov ah, 02h
    int 21h

    ; 光标右移一位(int10h ah=09h不会自动移动光标)
    mov ah, 03h
    int 10h
    inc dl
    mov ah, 02h
    int 10h

    inc si
    jmp print_loop

print_exit:
    pop dx
    pop cx
    pop bx
    pop ax
    ret
print_with_attr endp

prog  endp 
cseg  ends 
end prog 

代码说明

  1. 清屏操作:使用ANSI转义序列1Bh[2J配合int21h ah=09h快速清空屏幕。
  2. 显示属性配置:通过int10h ah=09h设置属性值0F0h,实现闪烁+黑字白背景的高亮效果(属性字节格式:位7为闪烁位,位6-4为背景色,位3-0为前景色)。
  3. 光标控制:用int10h ah=02h设置光标位置,int10h ah=03h获取当前位置后修改行号,实现上移两行的需求。
  4. 核心输出逻辑:严格使用int21h ah=02h逐个输出字符,配合属性设置子程序,确保每一个字符都符合高亮要求。
  5. 子程序封装:将字符输出与属性设置逻辑封装为print_with_attr,提升代码复用性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 03:55:56