引导加载程序在视频内存0xb8000上打印 [英] bootloader printing on video memory 0xb8000

查看:285
本文介绍了引导加载程序在视频内存0xb8000上打印的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在汇编编程中只有3-4天的时间.尝试在视频内存中打印字符串并通过qemu运行. 我希望这个程序能打印出你好世界.但是它什么也不打印. qemu窗口显示从硬盘启动...",没有其他内容

I am 3-4 days old in assembly programming. trying to print a string in video memory and running through qemu. I expected this program to print Hallo world. But it prints nothing. qemu window prints "Booting From Hard Disk ..." Nothing else

引导加载程序只允许16位吗?在那种情况下,我将如何做MMIO?我遵循的是

Is it only 16 bit that is allowed in bootloader ? in that case how will I do MMIO ? I was following actual page 32 [ENTERING 32-BIT PROTECTED MODE] of http://www.cs.bham.ac.uk/~exr/lectures/opsys/10_11/lectures/os-dev.pdf

[bits 32]
[org 0x7c00]

loop:
    mov edx, 0xb8000
    mov ah,  0x0f

    mov ebx, message
    mov ecx, 0x0
    call draw_string

    ;jmp self_loop
    ;jmp loop

self_loop:
    jmp self_loop

; take the stream begining from ebx
draw_string:
    mov al, [ebx]
    mov ah,  0x0f

    mov [edx], ax
    add ebx, 1
    add edx, 2

    cmp al, 0

    jne draw_string
    ret

message:
    db 'Hallo World', 0x0

times 510 -( $ - $$ ) db 0  ; When compiled , our program must fit into 512 bytes ,
                ; with the last two bytes being the magic number ,
                ; so here, tell our assembly compiler to pad out our
                ; program with enough zero bytes (db 0) to bring us to the
                ; 510th byte.
dw 0xAA55           ; Last two bytes (one word) form the magic number ,
                ; so BIOS knows we are a boot sector.

推荐答案

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

Example for the 16 bit realmode segmented addressing at CPU startup, where the default segment size is limited to 64 KB. In the real mode we can use 32 bit offset register(80386+), but an offset-address have to be pointed inside of the 64 KB size of the segment limit and can not be pointed to an address outside of the 64 KB segment size. (Because we do not need 32 bit offset register for to access an offset between 0 to FFFF, i use 16 bit offset register for this example.) For to access more than only 64 KB we can use an other segment register and/or we can store an other segment address into a segment register.

...

由于hello world消息的字节已放入代码段中,因此我们希望对数据段寄存器使用相同的段地址,以获取消息的每个字节.

Because the bytes of the hello world message are placed into the code segment, we want to use the same segment address for the data segment register, for to get each byte of the message.

mov ax,cs
mov ds,ax

现在,我们将文本模式视频缓冲区的段地址存储在额外的段寄存器中.

Now we store the segment address of the textmode video buffer in the extra segment register.

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

这篇关于引导加载程序在视频内存0xb8000上打印的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆