Memory 视频内存0xb8000上的引导加载程序打印

Memory 视频内存0xb8000上的引导加载程序打印,memory,video,assembly,bootloader,qemu,Memory,Video,Assembly,Bootloader,Qemu,我有3-4天的汇编编程经验。尝试在视频内存中打印字符串并运行qemu。 我希望这个节目能打印《哈罗世界》。但它什么也没印出来。qemu窗口打印“从硬盘引导…”没有其他内容 引导加载程序中只允许16位吗?在这种情况下,我将如何进行MMIO?我是按照实际的第32页[进入32位保护模式的 CPU启动时的16位realmode分段寻址示例,其中默认段大小限制为64 KB。在实模式中,我们可以使用32位偏移寄存器(80386+),但偏移地址必须指向段限制的64 KB大小之内,并且不能指向64 KB段大小之

我有3-4天的汇编编程经验。尝试在视频内存中打印字符串并运行qemu。 我希望这个节目能打印《哈罗世界》。但它什么也没印出来。qemu窗口打印“从硬盘引导…”没有其他内容

引导加载程序中只允许16位吗?在这种情况下,我将如何进行MMIO?我是按照实际的第32页[进入32位保护模式的


CPU启动时的16位realmode分段寻址示例,其中默认段大小限制为64 KB。在实模式中,我们可以使用32位偏移寄存器(80386+),但偏移地址必须指向段限制的64 KB大小之内,并且不能指向64 KB段大小之外的地址。(因为访问0到FFFF之间的偏移量不需要32位偏移量寄存器,所以本例中我使用16位偏移量寄存器。)要访问超过64 KB的数据,我们可以使用其他段寄存器和/或将其他段地址存储到段寄存器中

mov ax,0xb800  ; = this is a segment address and not a linear offset address
mov es,ax

lea bx,message ; Now we get the source address in BX
mov di,0x0     ; and the target address for output (upper left corner) in DI

call draw_string

self_loop:
jmp self_loop

; take the stream begining from DS:bx
draw_string:
mov al,[bx]    ; load a byte from the address of DS:BX
mov ah,0x0f

mov es:[di],ax ; store a word to the address of ES:DI
add bx,1
add di,2       ; increasing the target offset address

cmp al,0
jne draw_string
ret

因为hello world消息的字节被放在代码段中,所以我们希望对数据段寄存器使用相同的段地址,以便获得消息的每个字节

mov ax,cs
mov ds,ax
现在,我们将textmode视频缓冲区的段地址存储在额外段寄存器中

mov ax,0xb800  ; = this is a segment address and not a linear offset address
mov es,ax

lea bx,message ; Now we get the source address in BX
mov di,0x0     ; and the target address for output (upper left corner) in DI

call draw_string

self_loop:
jmp self_loop

; take the stream begining from DS:bx
draw_string:
mov al,[bx]    ; load a byte from the address of DS:BX
mov ah,0x0f

mov es:[di],ax ; store a word to the address of ES:DI
add bx,1
add di,2       ; increasing the target offset address

cmp al,0
jne draw_string
ret

当你这样做的时候,你没有处于保护模式,是吗?所以您需要使用分段寻址。我如何指定保护模式?我将如何指定段寻址?我正在使用
nasm-f bin file.asm-o file.bin编译,并使用
qemu-system-i386 file.bin运行