我正在使用TASM 1.4而我正在尝试制作一个输出,它将显示不同颜色的句子,所有这些都在同一个屏幕上。我可以制作一些显示彩色文字的东西,但这些文字都有相同的颜色。如何制作显示不同颜色的字符串/句子的内容? 例如,像:
Hi, what group would you like to join?
The Founders
The Vox Populi
“你好,你想加入哪个团体?”绿色的。 “创始人”呈蓝色。并且“The Vox Populi”红色,也许我想要另一个眨眼的句子?我只能将它们全部显示为蓝色或红色或绿色。有帮助吗? 感谢。
答案 0 :(得分:4)
我将提供一种通过DOS int 21h
实现此目的的方法。
原始海报说他们正在使用TASM 1.4(TASM安装程序),这是一个基于DOSBox的环境,带有TASM 3.0和Turbo Debugger 3.1。在DOS时代,有一个视频控制台驱动程序可以使用CONFIG.SYS
之类的命令添加到DEVICE=C:\DOS\ANSI.SYS
。此驱动程序增强了DOS int 21h
输出,因此您可以指定属性(背景颜色,前景色,闪烁);清除屏幕;重置为默认值(通常为黑色)。 DOSBox内置了ANSI.SYS的部分实现。以下代码利用了这些ANSI codes:
.model small
.stack 100h
.data
a_cls db 27, "[2J$" ; Clear entire screen in currently set attributes
a_reset db 27, "[0m$" ; Reset attributes to standard (black on white)
a_blink db 27, "[5m$" ; Characters blink (blink doesn't work in all environments)
a_bright db 27, "[1m$" ; Bright colored characters
a_dim db 27, "[2m$" ; Dim colored characters
a_fg_black db 27, "[30m$" ; Foreground colors
a_fg_red db 27, "[31m$"
a_fg_green db 27, "[32m$"
a_fg_yellow db 27, "[33m$"
a_fg_blue db 27, "[34m$"
a_fg_magenta db 27, "[35m$"
a_fg_cyan db 27, "[36m$"
a_fg_white db 27, "[37m$"
a_bg_black db 27, "[40m$" ; Background colors
a_bg_red db 27, "[41m$"
a_bg_green db 27, "[42m$"
a_bg_yellow db 27, "[43m$"
a_bg_blue db 27, "[44m$"
a_bg_magenta db 27, "[45m$"
a_bg_cyan db 27, "[46m$"
a_bg_white db 27, "[47m$"
text1 db "Blinking Bright Yellow on Blue$"
text2 db " Back to Normal$"
text3 db " Bright Yellow on Black$"
combined db 27, "[0;5;2;31;42m Blinking Dim Red on Green$"
.code
begin:
mov ax,@data
mov ds,ax
mov es,ax
mov ah,09h
lea dx,a_cls ; clear screen
int 21h
lea dx,a_bright ; Bright colored characters
int 21h
lea dx,a_blink ; make the characters blink (if supported)
int 21h
lea dx,a_fg_yellow; make the characters yellow
int 21h
lea dx,a_bg_blue ; blue background for characters
int 21h
lea dx,text1 ; print text
int 21h
lea dx,a_reset ; reset to defaults
int 21h
lea dx,text2 ; print normal text
int 21h
lea dx,a_bright ; bright characters
int 21h
lea dx,a_fg_yellow; make the characters yellow
int 21h
lea dx,text3 ; print text
int 21h
lea dx,combined ; print combined text
int 21h
lea dx,a_reset ; reset to defaults before exiting back to DOS prompt
int 21h
.exit
end begin
在DOS中, ANSI 代码以 ESCAPE 字符(十进制27)开头,后跟 [(左括号)。对于属性,可以使用 m 命令。属性可以用分号分隔。除了 m 之外还有其他一些命令,它们可以在ANSI specs中找到。如果您查看上面的代码,您将看到我在哪些地方打破了原始海报可能感兴趣的许多命令的ANSI代码。
以下代码是组合多个属性(使用ANSI)而不是单独执行它们的示例。
combined db 27, "[0;5;2;31;42mBlinking Dim Red on Green$"
我们从 ESCAPE [开始。 0 将当前属性重置为默认值(大多数硬件在黑色时为白色)。其余属性由 SEMI COLONS 分隔。下一个属性 5 闪烁,下一个是 2 ,颜色变暗, 31 是前景色红色, 42 是绿色背景,后跟命令 m 。 m 结束命令,之后的字符是要打印的文本。
根据前面代码中的转义序列,以下内容将满足海报提出的具体问题:
.model small
.stack 100h
.data
a_reset db 27, "[0m$" ; Reset attributes to standard (black on white)
; 13, 10 is carriage return line feed combination(CR/LF)
line1 db 27, "[1;32mHi, what group would you like to join?", 13, 10, "$"
line2 db 27, "[1;34mThe Founders", 13, 10, "$"
line3 db 27, "[1;31mThe Vox Populi", 13, 10, "$"
line4 db 27, "[1;5;31;47mand maybe I'd want another sentence that blinks?$"
.code
begin:
mov ax,@data
mov ds,ax
mov es,ax
mov ah,09h
lea dx,line1 ; print line 1 (bright green)
int 21h
lea dx,line2 ; print line 2 (bright blue)
int 21h
lea dx,line3 ; print line 3 (bright red)
int 21h
lea dx,line4 ; print line 4 (blinking bright red on white background)
int 21h
lea dx,a_reset ; reset colors back to default before exiting
int 21h
.exit
end begin
已知Blink在DOSBox,VMWare,Bochs中工作,但在emu8086和Windows NT + DOS提示符下不起作用。
在这张海报的前一组评论中,其他related question我确实建议另一种方法是编写一个带字符串的过程或函数,并使用DOS中断和/或BIOS中断来更改字符的属性按字符为基础并将它们显示在屏幕上(同时跟踪光标)。最有效的方法是直接将属性写入视频内存(即0xb000:0)。上面我使用的ANSI.SYS方法是最容易开始的,并且应该在现代版本的DOSBox中默认工作。
答案 1 :(得分:4)
您可以将INT 10h / AH=13h
用于此目的:
.MODEL small
.STACK 1000h
.DATA
msg1 db "Hi, what group would you like to join?", 13, 10
msg1_len = $ - msg1
msg2 db "The Founders", 13, 10
msg2_len = $ - msg2
msg3 db "The Vox Populi", 13, 10
msg3_len = $ - msg3
msg4 db "Blinkers", 13, 10
msg4_len = $ - msg4
.CODE
main PROC
mov ax, @data
mov ds, ax ; Don't forget to initialize DS!
mov es, ax ; Segment needed for Int 10h/AH=13h
lea bp, msg1 ; ES:BP = Far pointer to string
mov cx, msg1_len ; CX = Length of string
mov bl, 2 ; green (http://stackoverflow.com/q/12556973/3512216)
call print
lea bp, msg2 ; ES:BP = Far pointer to string
mov cx, msg2_len ; CX = Length of string
mov bl, 3 ; blue (http://stackoverflow.com/q/12556973/3512216)
call print
lea bp, msg3 ; ES:BP = Far pointer to string
mov cx, msg3_len ; CX = Length of string
mov bl, 4 ; red (http://stackoverflow.com/q/12556973/3512216)
call print
lea bp, msg4 ; ES:BP = Far pointer to string
mov cx, msg4_len ; CX = Length of string
mov bl, 8Eh ; blinking yellow (Bit7 set, works at least in DOSBox)
call print
mov ax, 4C00h ; Return 0
int 21h
main ENDP
print PROC ; Arguments:
; ES:BP Pointer to string
; CX Length of string
; BL Attribute (color)
; http://www.ctyme.com/intr/rb-0088.htm
push cx ; Save CX (needed for Int 10h/AH=13h below)
mov ah, 03h ; VIDEO - GET CURSOR POSITION AND SIZE
xor bh, bh ; Page 0
int 10h ; Call Video-BIOS => DX is current cursor position
pop cx ; Restore CX
; http://www.ctyme.com/intr/rb-0210.htm
mov ah, 13h ; VIDEO - WRITE STRING (AT and later,EGA)
mov al, 1 ; Mode 1: move cursor
xor bh, bh ; Page 0
int 10h ; Call Video-BIOS
ret
print ENDP
END main