Search code examples
assemblyx86-16bootloadervga

How to go to new line in text mode assembly


I am currently making my own operating system. As I will be going into 32bit mode at some point, I am going to need to print to the screen without interrupts as they won't exist.

Here is my code so far:

org 0x7c00            ; add to offsets
xor ax, ax            ; make it zero
mov ds, ax            ; ds=0
mov ss, ax            ; stack starts at 0

cld

mov ax, 0xB800        ; Ax = address of video memory
mov es, ax
xor di, di


mov si, msg         ; load msg into si
call print            ; call thr print function

hlt

print:
  mov ah, 07h

printchar:
  lodsb               ; Hear we load a letter from si
  stosw
  cmp al, 0
  je done
  jmp printchar

done:
  ret                 ; return





msg db "Hello, World", 0   ; msg = 'test'
xpos   db 0
ypos   db 0


times 510-($-$$) db 0 ; make sure file is 510 bytes in size
dw 0xaa55             ; write boot signiture

When looking at the documentation, I know that to set the position of the character, I have to get position = (y_position * characters_per_line) + x_position;.

The only problem is, it doesn't seem to work. Even if I add one to the address so it is 0xB801, it does not move the text by one character. Instead, I get this: enter image description here.

What is going on here and how am I meant to print a character on a new line and also increment the x position by one?


Solution

  • Characters in VGA text mode are 2 bytes; one for the character and one for the attributes. +1 bytes is not the start of a character.

    But you're not adding 1 to the address, you're adding 1 to the segment base (0xB801), so you're going forward 16 bytes or 8 characters relative to the 0,0 position at the start of VGA memory at linear address 0xB8000.

    One character forward would be add di,2, because your current code is using es:di to store into VGA memory. (Or start with mov di,2 instead of zeroing it.)

    You wouldn't have to deal with segmentation if you switched to 32-bit protected mode with a flat 32-bit address space. You're not using any BIOS calls now, so you could.