Colored Hello World in TASM

21,384

Assembly language, as any programming language, is a result of arbitrary design decisions. Sometimes there can be a reason why a specific register is used as a interrupt call input register (optimization), but many times not, and you just have to take the interface (here int 10h or int 21h) as granted.

Related to your problem with several exclamation marks !!!!!!!!!!! (I assume 11 exclamation marks), you have incorrect parameters in your int 10 interrupt call:

mov cx,11

According to Ralf Brown's Interrupt List, the parameters for mov ah,9, int 10h are the following:

INT 10 - VIDEO - WRITE CHARACTER AND ATTRIBUTE AT CURSOR POSITION
    AH = 09h
    AL = character to display
    BH = page number (00h to number of pages - 1) (see #00010)
        background color in 256-color graphics modes (ET4000)
    BL = attribute (text mode) or color (graphics mode)
        if bit 7 set in <256-color graphics mode, character is XOR'ed
          onto screen
    CX = number of times to write character
Return: nothing
Notes:  all characters are displayed, including CR, LF, and BS
    replication count in CX may produce an unpredictable result in graphics
      modes if it is greater than the number of positions remaining in the
      current row
    With PhysTechSoft's PTS ROM-DOS the BH, BL, and CX values are ignored
      on entry.

So, instead of mov cx,11, it should be mov cx,1.

And the second mov al, hello[si] is redundant, because hello[si] has already been loaded into al at that time with the previous identical instruction. This doesn't affect the functioning of the code, however.

Edit: Added info on how to set and read the cursor location using int 10h.

It seems that you also need to update the cursor location with mov ah,2, int 10h, using the following parameters:

INT 10 - VIDEO - SET CURSOR POSITION
    AH = 02h
    BH = page number
        0-3 in modes 2&3
        0-7 in modes 0&1
        0 in graphics modes
    DH = row (00h is top)
    DL = column (00h is left)
Return: nothing

Possibly you may need need to read the current cursor position with mov ah,3, int 10h, using the following parameters:

INT 10 - VIDEO - GET CURSOR POSITION AND SIZE
    AH = 03h
    BH = page number
        0-3 in modes 2&3
        0-7 in modes 0&1
        0 in graphics modes
Return: AX = 0000h (Phoenix BIOS)
    CH = start scan line
    CL = end scan line
    DH = row (00h is top)
    DL = column (00h is left)
Notes:  a separate cursor is maintained for each of up to 8 display pages
    many ROM BIOSes incorrectly return the default size for a color display
      (start 06h, end 07h) when a monochrome display is attached
    With PhysTechSoft's PTS ROM-DOS the BH value is ignored on entry.
Share:
21,384
Aeolus Mateus
Author by

Aeolus Mateus

Updated on July 07, 2022

Comments

  • Aeolus Mateus
    Aeolus Mateus almost 2 years

    Good day. I'm new in assembly language and I'm trying to print a colored "Hello World" in TASM. Here is my code so far. It just prints "hello world" without a color.

    .model small
    .stack 100h
    
    .data
    message db 13,10,"Hello World!$"
    
    .code
    main proc near
       lea dx, message
       mov ah, 09h
       int 21h
    
       mov ah,4ch
       int 21h
    main endp
    


    I've read something like this

    mov ah,9    ;Function 9: Write character and attribute at cursor position
    mov al,'H'  ;AL = character to display
    mov bh,0    ;BH = page number
    mov bl,02EH ;BL = attribute (yellow on green)
    mov cx,1    ;CX = number of times to write character
    int 10H  ;Int 10H: Video (show the character)
    


    in a forum but I can't incorporate it with my hello world. I'm confused why use that particular register and the like. Please help me. Thank you very much!

    EDIT

    .model small
    .stack 100h
    
    .data
    hello db 'Hello World!',0
    
    .code
    main proc near
        mov ax, @data
        mov ds, ax
    
        mov ax, 3
        int 10h
    
        mov si, 0             ; cl is the counter register, set it to
                          ; zero (the first character in the string)
    
    start:                ; Beginning of loop
        mov al, hello[si]   ; Read the next byte from memory
        cmp al, 0           ; Compare the byte to null (the terminator)
        je endthis              ; If the byte is null, jump out of the loop
    
        mov ah, 09h
        mov al, hello[si]
        mov bh, 0
        mov bl,02EH
        mov cx,11
        int 10H  
    
        add si, 1           ; Move to the next byte in the string
        jmp start           ; Loop
    
    endthis:    
        mov ah, 4ch
        int 21h
    
    main endp
    end main
    
  • Aeolus Mateus
    Aeolus Mateus about 11 years
    Thank you! I've edited my code. It now prints in color but it prints "!!!!!!!!!!" instead of "Hello World!". What could the problem with my string manipulation be?
  • Aeolus Mateus
    Aeolus Mateus about 11 years
    Thank you for the information! However, when I changed it to 1, it just prints a single ! exclamation point. What could be done sir?
  • nrz
    nrz about 11 years
    CX = number of times to write character.
  • Aeolus Mateus
    Aeolus Mateus about 11 years
    I mean what happened to hello world. :) Why is it starting at the last character of the string?
  • nrz
    nrz about 11 years
    @AeolusMateus It seems that BIOS does not update the cursor position automatically. See my updated answer for the necessary int 10h calls and their parameters to update the cursor location.
  • Aeolus Mateus
    Aeolus Mateus about 11 years
    Thank you very much, sir! I added those row and column and it now worked. My problem now is how to display 13,10 as it is and not as garbage values. Anyway, I posted another thread for that. Thanks again!