The base address for the video memory in MS-DOS is
0xB8000. I am trying to write to this address using
debug.exe, but I am getting an error:
1165:0103 mov [b8000],ax ^ Error
You need to use a segment and offset, 0xB8000 can’t be represented directly in 16 bits:
mov ax, b800 mov ds, ax ; set AX appropriately here, or write an immediate value mov , ax
You need to go through another register to write to DS because
mov ds, imm16 isn’t valid.
Note that by writing a word (AX), you’re writing a character and its attribute in one operation (in text mode).
mov ax, imm16 is encoded as 0xB8, so
mov ax, b800 is 0xB800B8...
In monochrome video modes you’d have to use 0xB000 instead of 0xB800, and 0xA000 for some EGA/VGA graphics modes (see this table for details).
Another approach, as pointed out by tofro, is to use ES and the index registers:
mov ax, b800 mov es, ax xor di, di ; set AX appropriately here stosw
This has the same effect, using
stosw to write the contents of AX to the memory pointed at by ES:DI (and incrementing DI in the process, so the next
stosw writes to the next character on screen). This is how one would commonly go about writing to the screen, in combination with
movsw to copy content from DS:SI to ES:DI. For example, here’s how to clear the screen in 80×25 mode:
mov ax, b800 mov es, ax xor di, di mov cx, 07d0 mov ax, 2000 rep stosw
This writes 0x0020 (black-on-black space) to the screen 2000 times (80×25, 0x07D0).