How to print colored string in DOS?

后端 未结 3 1859
挽巷
挽巷 2020-12-02 01:52

I want to print the below set of datablock(s) in a different color other than the usual white text color which can be achieved by using another DOS interrupt (dx:string-addr

相关标签:
3条回答
  • 2020-12-02 02:15

    There are several ways to achieve your goal IN TEXT MODE :

    1. Display char by char : this way you can choose one color for every character.
    2. Access screen memory : at segment 0B800:0.
    3. Display the whole string with the same color.

    Next code does the job with the third option (the easiest). It was made with EMU8086:

    .stack 100h
    .data
    
    Jan   db  "         January           ",13,10 
          db  "Sun Mon Tue Wed Thu Fri Sat",13,10 
          db  "                 1   2   3 ",13,10 
          db  " 4   5   6   7   8   9  10 ",13,10 
          db  "11  12  13  14  15  16  17 ",13,10 
          db  "18  19  20  21  22  23  24 ",13,10 
          db  "25  26  27  28  29  30  31 "       
    color db 181
    
    .code          
    ;INITIALIZE DATA SEGMENT.
      mov  ax,@data
      mov  ds,ax 
    
    ;DISPLAY STRING WITH COLOR.
      mov  es,ax ;ES SEGMENT MUST POINT TO DATA SEGMENT.
      mov  ah,13h ;SERVICE TO DISPLAY STRING WITH COLOR.
      mov  bp,offset Jan ;STRING TO DISPLAY.
      mov  bh,0 ;PAGE (ALWAYS ZERO).
      mov  bl,color
      mov  cx,201 ;STRING LENGTH.
      mov  dl,0 ;X (SCREEN COORDINATE). 
      mov  dh,5 ;Y (SCREEN COORDINATE). 
      int  10h ;BIOS SCREEN SERVICES.  
    
    ;FINISH THE PROGRAM PROPERLY.
      mov  ax,4c00h
      int  21h
    

    Notice I removed the $ signs (because 13h service requires string length, not $). For a different color just change the value (181) for the "color" variable in data segment.

    To display diferent colors for diferent strings, copy-paste the display block for every string.

    Let us know if it worked for you.

    The formula to choose color goes like this:

    text-background * 16 + text-color

    Next are the colors :

    Black         =  0
    Blue          =  1
    Green         =  2
    Cyan          =  3
    Red           =  4
    Magenta       =  5
    Brown         =  6
    LightGray     =  7
    DarkGray      =  8
    LightBlue     =  9
    LightGreen    = 10
    LightCyan     = 11
    LightRed      = 12
    LightMagenta  = 13
    Yellow        = 14
    White         = 15
    

    With the given formula, if you want red background with yellow text you need the color 78 :

    4 * 16 + 14 = 78

    Now, let's do it in GRAPHICS MODE :

    .stack 100h
    .data
    
    Jan   db  "         January           ",13
          db  "Sun Mon Tue Wed Thu Fri Sat",13
          db  "                 1   2   3 ",13
          db  " 4   5   6   7   8   9  10 ",13
          db  "11  12  13  14  15  16  17 ",13
          db  "18  19  20  21  22  23  24 ",13
          db  "25  26  27  28  29  30  31 ",0
    color db 181
    x     db 0     ;SCREEN COORDINATE (COL).
    y     db 0     ;SCREEN COORDINATE (ROW).
    
    .code          
    ;INITIALIZE DATA SEGMENT.
      mov  ax,@data
      mov  ds,ax 
    
    ;SWITCH SCREEN TO GRAPHICS MODE.
      mov  ah,0
      mov  al,13h  ;320x240x256.
      int  10H
    
      mov  di, offset jan
    while:      
      call gotoxy  ;SET CURSOR POSITION FOR CURRENT CHAR.
      mov  al, [ di ]  ;CHAR TO DISPLAY.
      cmp  al, 13    ;IF CHAR == 13
      je   linebreak ;THEN JUMP TO LINEBREAK.
      cmp  al, 0   ;IF CHAR == 0
      je   finish  ;THEN JUMP TO FINISH.
      call char_display  ;DISPLAY CHAR IN AL WITH "COLOR".
      inc  x  ;NEXT CHARACTER GOES TO THE RIGHT.
      jmp  next_char
    linebreak:  
      inc  y  ;MOVE TO NEXT LINE.    
      mov  x, 0  ;X GOES TO THE LEFT.
    next_char:
      inc  di  ;NEXT CHAR IN "JAN".
      jmp  while
    
    finish:
    
    ;WAIT FOR ANY KEY.
      mov  ah,7
      int  21h
    
    ;FINISH THE PROGRAM PROPERLY.
      mov  ax,4c00h
      int  21h        
    
    ;-------------------------------------------------     
    ;DISPLAY ONE CHARACTER IN "AL" WITH "COLOR".
    
    proc char_display
      mov  ah, 9
      mov  bh, 0
      mov  bl, color  ;ANY COLOR.
      mov  cx, 1  ;HOW MANY TIMES TO DISPLAY CHAR.
      int  10h
      ret
    endp    
    
    ;-------------------------------------------------     
    proc gotoxy
      mov dl, x
      mov dh, y
      mov ah, 2 ;SERVICE TO SET CURSOR POSITION.
      mov bh, 0 ;PAGE.
      int 10h   ;BIOS SCREEN SERVICES.  
      ret
    endp
    

    My graphics algorithm requires the use of char(13) for linebreaks (not 13,10) and the string to finish with 0.

    0 讨论(0)
  • 2020-12-02 02:16

    Code For All combinations of foreground and background colors:

    Include Irvine32.inc
    
    .data
    
    str1 byte "F",0dh,0ah,0          ;character initialized (0dh,0ah for next line)
    
    foreground Dword ?               ;variable declaration
    background Dword ?
    counter Dword ?
    
    .code
    
    main PROC
    
    mov ecx,16                     ; initializing ecx with 16
    
    l1:                             ;outer loop
    mov counter,ecx
    mov foreground,ecx
    dec foreground
    mov ecx,16
    
    
    
    l2:                            ;inner loop
    
    mov background , ecx
    dec background
    
    mov eax,background      ; Set EAX = background
    shl eax,4               ; Shift left, equivalent to multiplying EAX by 16
    add eax,foreground      ; Add foreground to EAX
    
    call settextcolor       ;set foreground and background color
    
    
    mov edx, offset str1    ; string is moved to edx for writing
    call writestring
    
    
    loop l2                  ;calling loop
    
    mov ecx,counter
    
    loop l1
        exit
    main ENDP
    END main
    
    0 讨论(0)
  • 2020-12-02 02:23
    Include Irvine32.inc
    
    .data
    
    str1 BYTE "different color string",0dh,0ah,0        ;string initializing
    
    counter dword ?                                     ;save loop value in counter
    
    .code
    
    main PROC
    
    mov ecx,4                                          ;loop repeated 4 times
    
    l1:
        mov counter,ecx                                ;counter save loop no
    
        mov eax,counter                          ;eax contain loop no 
                                                    ;which is equal to counter
                                                                               ; color no
    
        call    SetTextColor                           ;Call color library
    
        mov edx,offset  str1                       ;string reference is moved to edx
    
        call    WriteString                            ;string is write from reference
    
    loop l1                                            ; calling loop l1
    
        exit
    main ENDP
    END main
    
    0 讨论(0)
提交回复
热议问题