2015-09-17 20 views
2

我正在使用TASM 1.4,我试图做一个输出,将显示不同颜色的句子,都在同一个屏幕上。我可以制作显示彩色文本的东西,但所有文字都具有相同的颜色。我如何制作显示不同颜色的字符串/句子的东西? 例如,像:TASM 1.4 - 显示特定的彩色字符串?

Hi, what group would you like to join? 
The Founders 
The Vox Populi 

随着“嗨,你想哪个组加入?”绿色。 “创始人”染成蓝色。而“Vox Populi”红色,也许我想要另一个闪烁的句子?我只能将它们全部显示为蓝色或红色或绿色。任何帮助? 谢谢。

+1

的可能重复[?TASM 1.4 - 改变背景颜色,但不清除屏幕(http://stackoverflow.com/questions/32619237/tasm-1 -4-changing-background-color-without-clearing-the-screen) –

+0

@RossRidge嗨!呃,不,这实际上是一个不同的问题。在那里,我试图改变输入背景而不清除以前的文本,但在这里,我只是试图在同一屏幕上显示不同的彩色文本。 – xTan

+1

如果我的模糊内存是正确的,DOS中断不是很好。 BIOS中断10h,子功能13h可能是你想要的。甚至会做“彩虹”文字,每个角色都有不同的颜色。你认识拉尔夫布朗吗? –

回答

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 
+0

只是一个侧面说明,闪烁的地方不会工作是在32位Windows DOS提示 –

+0

@MichaelPetch:第二个是emu8086。但是这个问题涉及到“TASM 1.4”,也就是DOSBox--就像你刚才提到的那样,我查了一下。 – rkhb

+0

我之所以提到它的原因是因为像我一样评论了闪烁的黄色闪烁(Bit7集合,至少在DOSBox中有效),有人可能想知道你和我所暗指的环境可能不支持它,正如我所说的是一个侧面说明,并没有说我没有看到你的内联评论;-)。而且值得眨眼的东西似乎在Bochs中得到了支持。我做了 - 投票你的答案,因为它是另一种方式来剥皮这只猫。 –

4

我打算提供一种实现DOS的方法int 21h

原始海报称他们使用的是TASM 1.4(TASM安装程序),它是基于DOSBox的环境,包含TASM 3.0和Turbo Debugger 3.1。在DOS的时代,有一个视频控制台驱动程序,可以通过DEVICE=C:\DOS\ANSI.SYS等命令将其添加到CONFIG.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[。 将当前属性重置为默认值(大多数硬件是黑色的白色)。其余属性由SEMI COLONS分隔。的下一个属性闪烁,接下来是其变暗颜色,是前景色红色,是绿色背景后跟命令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 

闪烁已知在DOSBox中,VMWare的,Bochs的工作,但没有工作, emu8086和Windows NT + DOS提示符。

在这张海报的其他评论中,其他related question我的确提出了另一种方法,即编写一个程序或函数,它需要一个字符串并使用DOS中断和/或BIOS中断来逐字改变字符的属性并将它们显示在屏幕上(同时跟踪光标)。最有效的方法是直接将属性写入视频内存(即0xb000:0)。上面我使用的ANSI.SYS方法是最简单的,并且应该在现代版本的DOSBox中默认使用。