如何在文本模式下转到新行

时间:2018-10-04 22:21:35

标签: assembly x86-16 bootloader vga

我目前正在制作自己的操作系统。由于在某个时候我将进入32位模式,因此我将需要在不中断的情况下打印到屏幕上,因为它们将不存在。

到目前为止,这是我的代码:

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

看着documentation时,我知道要设置字符的位置,我必须得到position = (y_position * characters_per_line) + x_position;

唯一的问题是,它似乎不起作用。即使我将一个地址添加为0xB801,它也不会将文本移动一个字符。相反,我得到了这个:enter image description here

这是怎么回事,我是什么意思在新行上打印一个字符并将x位置增加一个?

1 个答案:

答案 0 :(得分:2)

VGA文本模式下的字符为2个字节;一个用于字符,另一个用于属性。 +1个字节不是字符的开头。

但是您没有在地址上加1,而是在段基(0xB801)上加1,因此相对于0,0位置,您要前进16个字节或8个字符VGA内存从线性地址0xB8000开始。

向前一个字符为add di,2,因为您当前的代码正在使用es:di存储到VGA内存中。 (或者以mov di,2开头而不是将其清零。)

如果切换到具有32位平面地址空间的32位保护模式,则无需处理分段。您现在不使用任何BIOS调用,因此可以。