【问题标题】:Bootloader memory location引导加载程序内存位置
【发布时间】:2014-03-19 05:54:11
【问题描述】:

这是我正在学习的引导加载程序的一部分

`[ORG 0x00]
[BITS 16]

SECTION .text

jmp 0x07c0:START                ; set CS(segment register) to 0x07C0 and jump to START label. 
TOTALSECTORCOUNT:
    dw  0x02
KERNEL32SECTORCOUNT:
    dw  0x02

START:
    mov ax, 0x07c0
    mov ds, ax                  ; set DS(segment register) to the address of the bootloader. 

mov ax, 0xb800
mov es, ax                      ; set ES(segment register) to the address of the video memory starting address. 

; stack initialization
mov ax, 0x0000
mov ss, ax
mov sp, 0xfffe
mov bp, 0xfffe

; clear the screen
mov si, 0
CLEARSCREEN:
    mov byte[es:si], 0
    mov byte[es:si + 1], 0x0a

    add si, 2
    cmp si, 80 * 25 * 2

    jl CLEARSCREEN

; print welcome message`

开头没看懂:jmp 0x07C0:STARTCS寄存器怎么设置? TOTALSECTORCOUNTKERNEL32SECTORCOUNT 这两个变量是什么?它们不会出现在引导扇区文件中的任何位置,如果我删除它们,引导加载程序将无法加载欢迎消息。

移除部件会导致操作系统无法加载。那么那个jmp语句和这两个变量有什么意义呢?

``[ORG 0x00]
[BITS 16]

jmp START


START:
    mov ax, 0x07c0
    mov ds, ax                  ; set DS(segment register) to the address of the bootloader. 

mov ax, 0xb800
mov es, ax                      ; set ES(segment register) to the address of the video memory starting address. 

; stack initialization
mov ax, 0x0000
mov ss, ax
mov sp, 0xfffe
mov bp, 0xfffe
`

【问题讨论】:

  • 我不知道这两个变量没有看到整个代码。

标签: bootloader osdev


【解决方案1】:

我不擅长汇编,通常也使用 AT&T 语法。不过我之前写过一个引导加载程序。

希望您已了解 16 位应用程序中使用的分段寻址系统。 cs 寄存器保存代码段http://wiki.osdev.org/Segmentation

jmp 0x07C0:START ;This is a long jump
jmp segment:offset

长跳转将cs 寄存器设置为段参数,然后跳转到偏移参数。当您进行短跳时,cs 寄存器不会改变。我假设它将包含0x0。您可以使用短跳转,但您必须告诉您的汇编器或链接器在哪里代码将运行。

编辑:再次阅读代码后,有[org 0x00] 行。这会将cs 寄存器默认设置为0x00。如果您想使用短跳转,请尝试将此行更改为 [org 0x7c00]

【讨论】:

  • 我不小心删除了这个问题。谢谢回答!我问了另一个涉及这两个变量的问题。我不确定他们为什么在那里,但这与图像创建者有关。 stackoverflow.com/questions/22522879/floppy-disk-sector-count
  • [org 0x00] 没有设置 CS 寄存器。设置段寄存器取决于代码。 [org 0x00] 将根据 ORG 指令生成虚拟内存地址。正确设置它们的责任取决于开发人员。
【解决方案2】:

CS 应该已经被 BIOS 设置为 0x7c00 所以行:

jmp 0x07c0:START

可以替换为:

jmp START

您提到的两个变量必须在代码的其他地方使用才能加载内核。但是,您似乎没有在此处发布整个代码。

看不到引导扇区的其余代码,我们无能为力。

【讨论】:

  • 这实际上是不正确的。您不应该假设 CS 是您想要的值。一些 BIOS 实际上会跳转到您的代码,其中 CS 是 0x07c0 和 0x0000 作为 IP。这是有效的,因为它也映射到物理地址 0x07c00。我写了一个关于 might be the case 的情况的 SO Q&A。这就是为什么您不应该盲目地将 CS 复制到 ES 和 DS,而应该将它们明确设置为您期望的值。如果您编写的代码不依赖于 CS 的值作为特定值,那么它很好
  • 我假设 cs 总是设置为 0x7c0。那我的坏。感谢您的澄清。
猜你喜欢
  • 1970-01-01
  • 2015-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-23
  • 2020-05-31
相关资源
最近更新 更多