我目前正在制作自己的操作系统。由于在某个时候我将进入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
,它也不会将文本移动一个字符。相反,我得到了这个:。
这是怎么回事,我是什么意思在新行上打印一个字符并将x位置增加一个?
答案 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调用,因此可以。