【问题标题】:Printing string to BIOS Video Memory not working将字符串打印到 BIOS 视频内存不起作用
【发布时间】:2016-12-02 08:13:49
【问题描述】:

所以,我使用 Bochs 来运行我的引导加载程序和 https://www.cs.bham.ac.uk/~exr/lectures/opsys/10_11/lectures/os-dev.pdf 第 4.1 章。

我试图通过直接写入视频内存来打印到 BIOS 控制台,但是当我运行 Bochs 时,我没有看到打印的字符串。该代码实际上与 PDF 上的代码相同。 错过了什么吗?是否有我忘记的 Bochs 设置或 PDF 没有告诉我的内容?

这是包含函数的汇编文件

 ;
; A simple collection of string routines for 32-bit protected mode.
;
[bits 32]
VIDEO_MEMORY equ 0xB8000
WHITE_ON_BLACK equ 0x0f         ; Color mode for the text to be written

PrintString:    ; Assume ebx holds memory address of string.
    ; edx will hold start of video memory
    ; Recall that each character written will take up 2 bytes of video memory
    ; So any particular row or column on the screen will have mem location = 0xb80000
    ; + 2 * (80r + c)

    ; The way this code is written, its always writing starting from the start of the
    ; video memory at 0xb8000, the top left of the screen, replacing everything there.

    pusha
    mov edx, VIDEO_MEMORY

    PrintLoop:
        mov al, [ebx]            ; Only ebx can be used to index
        mov ah, WHITE_ON_BLACK

        cmp al, 0
        je ExitRoutine

        mov [edx], ax

        inc ebx
        add edx, 2

        jmp PrintLoop

    ExitRoutine:
        popa
        ret

这是我的实际启动逻辑。

;
; A simple boot sector program that loops forever.
;

[bits 32]
[org 0x7c00]

mov ebx, welcome_msg
call PrintString

jmp $

%include "string_utils.s"

welcome_msg db 'WELCOME TO BASICOS OMFG!', 0
goodbye_msg db 'Goodbye! Thanks for using my BasicOS!', 0

times 510 -( $ - $$ ) db 0

dw 0xaa55

【问题讨论】:

  • DS的值是多少?
  • 您知道代码是用于 32 位保护/虚幻模式的吗?您的引导加载程序不仅仅是第二个 sn-p 中的内容,对吧?
  • 由于您的目标代码是 16 位实模式(您的引导加载程序没有切换到保护模式),您需要使用 bits 16 而不是 bits 32 。由于 386 机器和大多数 386 仿真器中的 BIOS 启动方式存在怪癖,它们最终以unreal mode 结尾。您应该能够将具有 32 位地址的 32 位寄存器用于具有 16 位指令的数据。这当然不适用于 8086 或 80286 处理器(可能还有一些古老的 80386 硬件)
  • 我的评论不适用于 BOCHS
  • 谢谢大家,但我找到了问题所在。我没有正确切换到保护模式。现在一切都很好。

标签: assembly operating-system bootloader bochs video-memory


【解决方案1】:

由于您处于引导加载程序中,因此您当前处于实模式,因此您不能将其作为长模式地址写入。而是将DS 设置为0xb800,然后使用ebx 作为偏移量:

mov ax, 0xb800
mov ds, ax
mov bx, 0
mov [bx], 0x412e  ; A with a green background, yellow foreground

否则,您将写入 DS 当前所在位置的偏移量。

【讨论】:

  • 在虚幻模式下,32 位寻址将与大多数 BIOS 在启动时设置的缓存描述符一起使用。我希望他的代码只需将bits 32 替换为bits 16 并在大多数80386 硬件(包括386 个VM 和模拟器)上运行即可工作。但是,像你一样直接为实模式编程当然可以在 8086+ 上工作,这是一个奖励。
  • 我认为他在这里有一个引导扇区,所以虚幻模式不会真正适用。我基于他的 ORG 声明和他在代码中所写内容的上下文。
  • 大多数 386 BIOS(包括虚拟的)启动到虚幻模式。在到达引导扇区之前,它们实际上已经切换到保护模式以进行一些处理并在引导扇区运行之前返回。很多人没有意识到这一点,您的代码不会关心正在使用哪种实模式(正如我所说的奖励)。我只是观察到,使用 OPs 代码,他可能会发现他的代码只需使用 bits 16 就可以按预期工作。
  • 啊,这很有趣。我没有意识到这一点。谢谢。
  • 我发现了问题所在。我没有正确切换到保护模式。现在一切都很好。从字面上看,我花了 15 天时间才弄清楚。没什么大不了的,现在我知道了。
猜你喜欢
  • 1970-01-01
  • 2015-02-04
  • 1970-01-01
  • 2013-06-22
  • 2013-03-28
  • 2014-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多