user123
user123

Reputation: 2884

Writing to memory mapped VGA at 0x000B8000 doesn't print characters

If I use:

mov ah, 0x00
mov al, 0x03
int 0x10

to set the video mode and then:

mov dword [0xb8000], 0x0769

to print a character to VGA buffer it doesn't do anything.

Is the information I'm getting from websites too old? Or I'm doing something wrong?

Upvotes: 2

Views: 1564

Answers (1)

Seva Alekseyev
Seva Alekseyev

Reputation: 61351

The offset in real mode is limited to 0xFFFF. This is not a flat 32-bit address space that we know and love. Assembling your code with NASM 2.14.02 produces this machine code (with ndisasm disassembly shown):

66 C7 06 0080 69070000   mov dword [0x8000],0x769
******************       warning: word data exceeds bounds [-w+number-overflow]

If your version of NASM or whatever assembler you're using didn't warn you that you were making this mistake, update it or use the warning options it does have.


What do do instead

Instead, set ES to 0xB800 and use it as the segment:

mov ax, 0xb800
mov es, ax
mov word [es: 0], 0x0769

On a side note, a single screen character in text mode corresponds to a WORD in video memory, not a DWORD. A byte for the character, another byte for attributes.


If you were trying to override the address size instead of the operand-size, to use a DWORD address with an address-size prefix: that's possible but won't do what you want. The segment limit is still 64k. But just for the record, the NASM syntax is

mov  word [dword 0xb8000], 0x0769      ; will #GP fault because of segment limit
; 67 C7 05 00800B00 6907

Upvotes: 4

Related Questions