Assembly 如何在文本模式汇编中转到新行
我目前正在制作自己的操作系统。由于我将在某个时候进入32位模式,我需要在不中断的情况下打印到屏幕上,因为它们不存在 以下是我目前的代码:Assembly 如何在文本模式汇编中转到新行,assembly,x86-16,bootloader,vga,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 =
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
当查看时,我知道要设置字符的位置,我必须得到position=(y_position*characters_per_line)+x_position代码>
唯一的问题是,它似乎不起作用。即使我在地址中添加一个字符,使其成为0xB801
,它也不会将文本移动一个字符。相反,我得到了这个:
这里发生了什么?我如何在新行上打印一个字符并将x位置增加一个?VGA文本模式中的字符为2字节;一个用于角色,一个用于属性+1字节不是字符的开头
但您并没有将1添加到地址,而是将1添加到段基(0xB801
),因此您将向前移动16个字节或8个字符,相对于线性地址0xB8000处VGA内存开始处的0,0位置
向前一个字符将是添加di,2
,因为您当前的代码正在使用es:di存储到VGA内存中。(或以mov di,2开始,而不是将其归零。)
如果切换到32位保护模式,并使用平坦的32位地址空间,则不必处理分段。您现在没有使用任何BIOS调用,因此您可以。请正确标记您的问题,这样我们就不必一直为您编辑这些问题。它在描述中说得对,因为它本身太模糊了。x86不是唯一的体系结构,例如,引导加载程序与在Linux下运行的64位代码非常不同。@PeterCordes抱歉!我不确定还要用什么标签。谢谢你以后让我知道。@PeterCordes,你说的16字节或8个字符是什么意思?还有,我打算使用什么寄存器来指定位置?您可以使用您想要的任何寄存器。您当前正在使用DI作为相对于VGA基的字节偏移量(您将其放入es
)。。。在标准80x25(或其他80x???)文本模式下,下一行是+160字节(80*2),因此行从实模式地址开始B800:0000
,B800:00A0
,B800:0140
,B800:01E0
,等等。。。(当然,您可以在实模式下通过许多其他变量来组合该地址,例如B800:01E0
也是B81E:0000
,等等……但是您可能希望将段固定到B800
,并且只移动偏移部分。在32b平面模式下,没有矛盾,bu8000
只能以这种方式寻址(在不创建内存映射的情况下,该区域也会在其他地方出现别名…)。