I have a function defined for print, it's called printf, and it's like this:
    mov ah, 0eh
    mov bl, 0fh

    or al, al
        jz .return
        int 10h
        jmp .nextchar


But it isn't displaying blue as the foreground. What I got is that normal gray, but why I'm getting this? What I need to do?

Best Regards,
Nathan Paulino Campos
Posted on 2010-06-19 08:52:58 by nathanpc

Read carefully. Foreground color in bl is for graphic modes only. For text modes, correct bh is much more significant.
Posted on 2010-06-19 12:42:06 by baldr
I'm still having the same problem. :sad:
Posted on 2010-06-19 12:58:23 by nathanpc
From my "experience" (more what I've "heard" than what I've "done"), int 10h/0Eh is "shakey" on printing colors - some video biosen will, and some won't. Int 10h/09h may be better - it doesn't advance the cursor, so you'll have to do that (two more interrupts). Int 10h/13h (?) - the one that takes the "string" in es:bp(!) is probably a better bet for printing colors... You can make "each character different" or "all characters what's in bl" and advance the cursor or not, depending on what's in al. An "odd" interrupt, but powerful...


Posted on 2010-06-19 13:24:49 by fbkotler

int10/0E is just as said, teletype-like output. It prints on the paper provided (unless you're in graphic mode where you have to have at least foreground color).

If you don't have really weird videocontroller, why don't use plain-and-straightforward lodsb / stosw?


Don't fiddle with printf except you provide similar services (like "%#*-.8x"). ;-)
Posted on 2010-06-19 14:15:46 by baldr
I agree that lodsb/stosw is "the way to go". Straightforward, and faster, besides (not that it matters - it'll print faster than we can read it in any case). It would meant that you'd have to "do something" with CR/LF/TAB/BS etc... Have to do most of it anyway...


Posted on 2010-06-19 15:58:17 by fbkotler
Ok, but being at text mode, what I can do? Without doing that strange, but useful use of the language that fbkotler said. :|
Posted on 2010-06-19 17:51:25 by nathanpc
What is it you *want* to do, Nathan? As baldr points out, you're using the "teletype" interrupt. I have been told that it actually *does* use the color in bl on some machines, but not on mine, and evidently not on yours. You're putting 0Fh in bl, which would give you "bright white", not "blue", anyway.

If you don't want to use the bios ints that *do* print colors (9 and 13h, IIRC), try this:

; nasm -f bin -o hwnoint.com hwnoint.asm

org 100h

    push word 0B800h    ; segment of video memory
    pop es              ; (because stosw uses es:di)
    mov di, (10 * 80 + 30) * 2  ; offset into screen
        ; (row * width + column) * 2 bytes/character
    mov si, msg        ; offset of our string
    mov ah, 0B0h        ; color (blinking black on cyan)
    lodsb              ; get byte from into al
                        ; and increment si for next one
    or al, al          ; this doesn't change al, but sets
    jz depart          ; the flags - if zero, we're done
    stosw              ; stores ax (char & color) to
                        ; and add 2 to di for next one
    jmp short top      ; do more
    ret                ; return to dos (or other caller)

msg db " Look, Ma! No ints! ",0  ; note 0, not '$', terminated
                                ; '$' is just for int 21h/9

Heck, might as well give you my int 10h/13h example, too. This is more complicated than it needs to be - I "rotate" the colors (in a rather stupid way) - but you can probably extract the "essence".

org 100h

segment .data
              ; message in char,attrib,char,attrib... format
    msg1 db 'M',01h,'a',02h,'n',03h,'y',04h,' ',05h,'T',06h
        db 'h',07h,'a',08h,'n',09h,'k',0Ah,'s',0Bh,' ',0Ch
        db 't',0Dh,'o',0Eh,' ',0Fh,'R',01h,'a',02h,'l',03h
        db 'f',04h,' ',05h,'B',06h,'r',07h,'o',08h,'w',09h
        db 'n',0Ah,'!',0Bh      ; no need to terminate...
    msg1len dw $-msg1            ; let the assembler count 'em!

segment .text

    mov ax, 3        ; reset video mode to 3 (cheesy CLS)
    int 10h          ; call bios video services
    mov bp, msg1      ; point to string
    mov cx, ; length of string - chars + attributes
    shr cx, 1        ; div by two to get char-only len for the call
    mov dh, 0Bh      ; row
    mov dl, 1Ah      ; column
    mov bh, 0        ; video page "usually" (?) zero
                      ; don't care what BL is for this AL
    mov ah, 13h      ; write string in ES:BP at DH,DL (row,column)
    mov al, 2        ; char, attr,... format - no cursor update
                      ; 3 - char,attrib - update  cursor
                      ; 1 - attrib in BL - update cursor
                      ; 0 - attrib in BL - no update
    int 10h          ; call video services (AT+,EGA+ ???)
                      ; rather than alter the pallette, we just
    mov bx, msg1      ; change the colors in the string, and
    mov cx, ; reprint it (no cursor update :) ! )
    shr cx, 1        ; number of colors
    inc bx            ; skip over character
    mov al,      ; get current color
    inc al            ; bump it
    cmp al, 10h      ; we only change low nibble - high nibble
    jnz colorok      ; is background (bit 7 set - FG blinks)
    mov al, 1        ; we don't want color zero (black), or we
colorok:              ; could just "or al,0Fh"
    mov , al      ; stuff it back in the string
    inc bx            ; point to next character
    loop morecolors  ; do 'em all
    mov cx, 2        ; BIOS is "slow", but we still
    call DELAYCX      ; need some delay
    mov ah, 1        ; check keyboard status
    int 16h
    jz domore        ; no key hit - do it again
    mov ah, 0        ; get the key off the buffer
    int 16h
                      ; could clearscreen again here, but
exit:                ; naw, let's leave it...
    mov ah, 4Ch      ; scram
    int 21h

; twiddle thumbs for cx/18.2 seconds
        push ax
        push bx
        push ds
        mov bx, 40h        ; BIOS data segment
        mov ds, bx
        mov bx, 6Ch        ; BIOS timer, 40:6C
        mov ax,
        add ax, cx
        cmp ax,         ; Is it the same?
        jnc DelayLoop      ; No, try again.
        pop ds              ; Restore registers and exit.
        pop bx
        pop ax

I don't think I have an example of int 10h/9 at hand. It'll print the color in bl, but you'll need to update the cursor yourself (getcursor/setcursor). Look it up. You *do* know about Ralf Brown's Interrupt List,  right? If not, look here:


I think I like the lodsb/stosw method best...


Posted on 2010-06-19 20:28:51 by fbkotler
The first one I understood very fast, because when I was designing my OS using C, I use that as a pointer to print things on the screen. Anyway, when I tried this now, my OS don't want to boot. :(
Posted on 2010-06-19 21:28:09 by nathanpc
Well, they won't run on Linux, either. As posted, they're intended to be .com files. If they're preventing your OS from booting... sounds like an OS problem to me! :)

Any luck tracking it down, Nathan?


Posted on 2010-06-21 09:26:39 by fbkotler