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

8086汇编:字符串比对后彩色显示的颜色修改问题求助

8086汇编彩色显示字符串问题

我是汇编语言新手,现在需要完成以下8086汇编程序开发任务:从键盘输入两行不超过50字符的字符串,按规则彩色显示字符——两行共有的字符显示为红色,第一行独有的字符显示为蓝色,第二行独有的字符显示为黄色。目前我已完成字符串输入部分,但无法实现文本颜色修改,现有实现代码及尝试的无效代码如下:

现有代码

.model small

.data
message1 db "Enter any string: $"
message2 db "Given string is :$"
str1 db 50 dup('$')
str2 db 25 dup('$')

.code

mov ax,@data
mov ds,ax   
;--------------------------------------------------
; disply first massege:
mov dx,offset message1    ; Enter any string: 
mov ah,09h
int 21h    
;adding new line
;--------------------------------------------------
call new_line
;--------------------------------------------------
;fist strig up to 25 char
firstString:
lea dx, str1
mov str1,26
mov ah,10
int 21h

;adding new line
;--------------------------------------------------
call new_line 
;--------------------------------------------------   
;second string up to 25 char
lea dx, str2
mov str2,26
mov ah,10
int 21h

;adding new line
;--------------------------------------------------
call new_line        

;disply the input
;-------------------------------------------------- 
mov dx,offset message2
mov ah,09h
int 21h 

;adding new line
;--------------------------------------------------
call new_line
;first string
;------------
mov cl,str1[1]
mov si,2
Output:
mov dl,str1[si]
mov ah,2
int 21h
inc si
loop output        
;adding new line
;--------------
call new_line
;second string
;-------------
mov cl,str2[1]
mov si,2
Output2:
mov dl,str2[si]
mov ah,2
int 21h
inc si
loop output2         
exit:


mov ah,4ch
int 21h

new_line proc near
mov dl,10
mov ah,2
int 21h
mov dl,13
mov ah,2
int 21h   
ret 
new_line endp   


end

尝试的无效代码

mov si, 2
mov ch, 25 ;I have the max 25 char so I figured that I need to loop 25 times
color:
MOV AH,09         ; FUNCTION 9
MOV AL,str1[si] ; here i think i need to move my first element 
MOV BX,0004      ; PAGE 0, COLOR 4
MOV Cl,1 ; here I don't know how many elements I have because i take input from the user 
inc si
INT 10H              ; INTERRUPT 10 -> BIOS
INT 20H 
loop color             ; END

问题分析

你之前尝试的INT 10H AH=09H功能确实支持带颜色显示字符,但代码存在几个关键问题:

  1. INT 20H会直接终止程序,导致循环仅执行一次就退出
  2. 硬写25次循环,没有根据用户输入的实际字符长度处理,会输出多余空字符
  3. 缺少字符归属判断逻辑,无法根据“共有/独有”规则切换对应颜色

解决方案步骤

  1. 构建字符标记表:用256字节数组记录每个ASCII字符的出现情况(0=未出现,1=仅第一行,2=仅第二行,3=两行都有)
  2. 使用BIOS彩色输出功能:根据字符标记值选择对应颜色(红色=0x04,蓝色=0x01,黄色=0x0E)
  3. 修正循环逻辑:基于用户输入的实际长度循环,避免无效处理

修改后的完整代码

.model small
.stack 100h

.data
message1 db "Enter first string (max 25 chars): $"
message2 db "Enter second string (max 25 chars): $"
result_msg db "Colored result:",0Dh,0Ah,"$"

; 标准DOS输入缓冲区:[最大长度][实际长度][字符...]
str1 db 26, ?, 26 dup('$')  ; 最大25字符,预留字节存实际长度
str2 db 26, ?, 26 dup('$')

; 字符标记表:256字节,记录每个ASCII字符的归属
char_flag db 256 dup(0)

.code
main proc
    mov ax, @data
    mov ds, ax

    ; 输入第一行字符串
    mov dx, offset message1
    mov ah, 09h
    int 21h
    call new_line
    lea dx, str1
    mov ah, 10h
    int 21h
    call new_line

    ; 输入第二行字符串
    mov dx, offset message2
    mov ah, 09h
    int 21h
    call new_line
    lea dx, str2
    mov ah, 10h
    int 21h
    call new_line

    ; 标记第一行出现的字符
    mov cl, str1[1]  ; 第一行实际长度
    mov si, 2        ; 指向第一个字符
mark_str1:
    mov al, str1[si]
    or char_flag[al], 1  ; 标记为存在于第一行
    inc si
    loop mark_str1

    ; 标记第二行出现的字符
    mov cl, str2[1]
    mov si, 2
mark_str2:
    mov al, str2[si]
    or char_flag[al], 2  ; 标记为存在于第二行
    inc si
    loop mark_str2

    ; 显示结果标题
    mov dx, offset result_msg
    mov ah, 09h
    int 21h

    ; 彩色显示第一行字符串
    mov cl, str1[1]
    mov si, 2
display_str1:
    mov al, str1[si]
    ; 根据标记选择颜色
    mov bl, char_flag[al]
    cmp bl, 3
    je set_red
    cmp bl, 1
    je set_blue
set_red:
    mov bh, 0        ; 显示页码0
    mov bl, 04h      ; 红色前景色
    jmp display_char
set_blue:
    mov bh, 0
    mov bl, 01h      ; 蓝色前景色
display_char:
    mov ah, 09h      ; BIOS带颜色显示字符功能
    mov cx, 1        ; 显示1次
    int 10h
    call move_cursor_right  ; 手动移动光标避免重叠
    inc si
    loop display_str1
    call new_line

    ; 彩色显示第二行字符串
    mov cl, str2[1]
    mov si, 2
display_str2:
    mov al, str2[si]
    mov bl, char_flag[al]
    cmp bl, 3
    je set_red2
    cmp bl, 2
    je set_yellow
set_red2:
    mov bh, 0
    mov bl, 04h      ; 红色前景色
    jmp display_char2
set_yellow:
    mov bh, 0
    mov bl, 0Eh      ; 黄色前景色
display_char2:
    mov ah, 09h
    mov cx, 1
    int 10h
    call move_cursor_right
    inc si
    loop display_str2
    call new_line

exit:
    mov ah, 4Ch
    int 21h
main endp

; 换行子程序
new_line proc near
    mov dl, 0Ah
    mov ah, 02h
    int 21h
    mov dl, 0Dh
    mov ah, 02h
    int 21h
    ret
new_line endp

; 光标右移子程序(解决INT 10H AH=09H不自动移动光标问题)
move_cursor_right proc near
    mov ah, 03h      ; 获取当前光标位置
    mov bh, 0
    int 10h
    inc dl           ; 列数+1
    mov ah, 02h      ; 设置新光标位置
    int 10h
    ret
move_cursor_right endp

end main

代码说明

  1. 字符标记表:通过两次遍历字符串,用位运算标记字符归属,避免重复判断
  2. 颜色规则:
    • 红色(0x04):两行共有的字符
    • 蓝色(0x01):第一行独有的字符
    • 黄色(0x0E):第二行独有的字符
  3. 光标处理:INT 10H AH=09H不会自动移动光标,所以手动调用光标移动子程序避免字符重叠
  4. 输入缓冲区修正:将原字符串定义改为DOS输入功能(AH=10H)要求的标准格式,确保正确获取输入长度

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 11:35:19