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功能确实支持带颜色显示字符,但代码存在几个关键问题:
INT 20H会直接终止程序,导致循环仅执行一次就退出- 硬写25次循环,没有根据用户输入的实际字符长度处理,会输出多余空字符
- 缺少字符归属判断逻辑,无法根据“共有/独有”规则切换对应颜色
解决方案步骤
- 构建字符标记表:用256字节数组记录每个ASCII字符的出现情况(0=未出现,1=仅第一行,2=仅第二行,3=两行都有)
- 使用BIOS彩色输出功能:根据字符标记值选择对应颜色(红色=0x04,蓝色=0x01,黄色=0x0E)
- 修正循环逻辑:基于用户输入的实际长度循环,避免无效处理
修改后的完整代码
.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
代码说明
- 字符标记表:通过两次遍历字符串,用位运算标记字符归属,避免重复判断
- 颜色规则:
- 红色(0x04):两行共有的字符
- 蓝色(0x01):第一行独有的字符
- 黄色(0x0E):第二行独有的字符
- 光标处理:
INT 10H AH=09H不会自动移动光标,所以手动调用光标移动子程序避免字符重叠 - 输入缓冲区修正:将原字符串定义改为DOS输入功能(AH=10H)要求的标准格式,确保正确获取输入长度
内容的提问来源于stack exchange,提问作者nreta
相关产品推荐
相关产品推荐

