Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 如何在文本模式汇编中转到新行_Assembly_X86 16_Bootloader_Vga - Fatal编程技术网

Assembly 如何在文本模式汇编中转到新行

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 =

我目前正在制作自己的操作系统。由于我将在某个时候进入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
当查看时,我知道要设置字符的位置,我必须得到
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
只能以这种方式寻址(在不创建内存映射的情况下,该区域也会在其他地方出现别名…)。