为什么我们在引导程序开始时给出 ORG 7C00?

发布于 2024-10-31 13:20:52 字数 40 浏览 1 评论 0原文

引导加载程序无论如何都会在该地址加载它?为什么要在程序中指定这个?

The bootloader will anyway load it at that address? Why specify this to the program?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

小清晰的声音 2024-11-07 13:20:52

ORG 伪指令的作用是告诉汇编器将此偏移量添加到所有提到的绝对地址中。例如,如果您编写“MOV AX,my_string”并且 my_string 位于代码中的 1234 个字节,则汇编器会生成“MOV AX,7c00h+1234”。不太常见的是,它也以其他方式使用,从给定的绝对地址计算相对地址(例如短跳转)。

What the ORG pseudo instruction does is to tell the assembler to add this offset to all absolute addresses mentioned. For example if you write "MOV AX,my_string" and my_string gets located 1234 bytes into the code, then the assembler generates "MOV AX,7c00h+1234". Less commonly it is also used the other way around to calculate a relative address (such as for a short jump) from a an absolute address given.

海夕 2024-11-07 13:20:52

你在这里没有选择。阅读这篇文章:

http://en.wikibooks.org/wiki/X86_Assembly/Bootloaders

从上面的 URL 来看,BIOS(实际上是 PC 硬件)将跳转到 0000:7c00 处的内存,以继续以 16 位模式执行。

并引用上面的内容:

引导加载程序在某些条件下运行,程序员必须了解这些条件才能成功创建引导加载程序。下列
与 PC BIOS 启动的引导加载程序相关:

  • 第一部分
    驱动器包含其引导加载程序。
  • 一个扇区为 512 字节 — 最后一个扇区
    其中两个字节必须为 0xAA55(即 0x55 后跟 0xAA),或
    否则 BIOS 会将驱动器视为无法启动。
  • 如果一切都在
    命令,表示第一个扇区将放置在 RAM 地址 0000:7C00 处,并且
    当 BIOS 将控制权转移到 0000:7C00 时,它的角色就结束了。 (即它
    JMP 到该地址)

因此,从启动开始,如果您希望 CPU 开始执行您的代码,它必须位于内存中的 0000:7c00 处。这部分代码是从硬盘的第一个扇区加载的——也是由硬件完成的。并且仅加载第一个扇区,代码的其余部分必须由该初始“引导加载程序”加载。

更多信息请参见此处(有关硬盘启动扇区和 7c00 功能):

http://www.ata-atapi .com/hiwdos.html

http://www.ata-atapi.com/hiwmbr .html

请不要与 CPU 的启动模式混淆 - 它将获取并执行的第一条指令位于物理地址 0xfffffff0(参见第 9-5 页):

http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-vol-3a-part-1-manual。 pdf

并且在这个阶段它正在执行非易失性(意味着您无法轻松地对其进行重新编程,因此不属于引导加载程序的责任)BIOS 代码。

更新:2015 年 10 月 6 日

但是此 BIOS 代码确实有一些变化(如 Michael Petch 所强调的) - 某些 BIOS 将从 07c0:0000 而不是 0000:7c00 加载,并从“grub”引导加载程序中提取还有源代码:

.globl _start; _start:
        /*
         * _start is loaded at 0x7c00 and is jumped to with CS:IP 0:0x7c00
         */

        /*
         * Beginning of the sector is compatible with the FAT/HPFS BIOS
         * parameter block.
         */

        jmp     after_BPB
        nop     /* do I care about this ??? */

after_BPB:

/* general setup */
        cli             /* we're not safe here! */
boot_drive_check:
        jmp     1f
        testb   $0x80, %dl
        jnz     1f
        movb    $0x80, %dl
1:
        /*
         * ljmp to the next instruction because some bogus BIOSes
         * jump to 07C0:0000 instead of 0000:7C00.
         */
        ljmp    $0, $ABS(real_start)

You don't have a choice here. Read this article:

http://en.wikibooks.org/wiki/X86_Assembly/Bootloaders

From the above URL, BIOS (which is effectively PC hardware) will make the jump to memory at 0000:7c00 to continue execution in 16-bit mode.

And to quote from above:

A bootloader runs under certain conditions that the programmer must appreciate in order to make a successful bootloader. The following
pertains to bootloaders initiated by the PC BIOS:

  • The first sector of
    a drive contains its boot loader.
  • One sector is 512 bytes — the last
    two bytes of which must be 0xAA55 (i.e. 0x55 followed by 0xAA), or
    else the BIOS will treat the drive as unbootable.
  • If everything is in
    order, said first sector will be placed at RAM address 0000:7C00, and
    the BIOS's role is over as it transfers control to 0000:7C00. (I.e. it
    JMPs to that address)

So from bootup, if u want the CPU to start executing your code, it has to be located in memory at 0000:7c00. And this part of the code is loaded from the first sector the harddisk - also done by hardware. And it is only the first sector which is loaded, the remaining of other parts of the code then have to be loaded by this initial "bootloader".

More information here (on harddisk bootup sector and the 7c00 feature):

http://www.ata-atapi.com/hiwdos.html

http://www.ata-atapi.com/hiwmbr.html

Please don't confuse with the starting up mode of the CPU - the first instruction it will fetch and execute is at physical address 0xfffffff0 (see page 9-5):

http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-vol-3a-part-1-manual.pdf

and at this stage it is executing non-volatile (meaning you cannot reprogram it easily, and thus not part of bootloader's responsibility) BIOS code.

Update: 6 Oct 2015

But this BIOS code does have some variation (as highlighted by Michael Petch) - some BIOS will load from 07c0:0000 instead of 0000:7c00, and as extracted from "grub" bootloader source code as well:

.globl _start; _start:
        /*
         * _start is loaded at 0x7c00 and is jumped to with CS:IP 0:0x7c00
         */

        /*
         * Beginning of the sector is compatible with the FAT/HPFS BIOS
         * parameter block.
         */

        jmp     after_BPB
        nop     /* do I care about this ??? */

after_BPB:

/* general setup */
        cli             /* we're not safe here! */
boot_drive_check:
        jmp     1f
        testb   $0x80, %dl
        jnz     1f
        movb    $0x80, %dl
1:
        /*
         * ljmp to the next instruction because some bogus BIOSes
         * jump to 07C0:0000 instead of 0000:7C00.
         */
        ljmp    $0, $ABS(real_start)
画骨成沙 2024-11-07 13:20:52

您没有给出这个问题的任何背景。但我会尝试给出某种形式的答案。

当程序加载到内存后执行时,程序必须位于某个地方,假设这是地址7C00。处理器开始在某个地方执行,在您的情况下很可能是 7C00。 ORG 语句告诉汇编器以下指令的地址将出现在该地址处。

为什么不是0?好吧,您的处理器可能需要这些地址上的其他东西,即。中断向量。

您的处理器的数据表将为您提供有关其启动顺序的更多信息。

祝你好运。

来自快速的好...

http://f.osdev.org/ viewtopic.php?f=1&t=9543

You have not given any context for this question. But I will attempt to give some form of answer.

When the program is executed after being loaded into memory the program must be located somewhere, imagine this is address 7C00. The processor starts excuting somewhere, in your case most likely 7C00. The ORG statement is telling the assembler that addresses for the following instructions will appear at this address.

Why not 0? Well, your processor may want other things at those addresses, ie. interrupt vectors.

The datasheet for your processor will give you more information on its startup sequence.

Good luck.

From a quick goodle...

http://f.osdev.org/viewtopic.php?f=1&t=9543

孤千羽 2024-11-07 13:20:52

我对此也很困惑。看起来这取决于您的代码和链接参数。如果您查看 grub2 中的 boot.S,它没有“.org 0”或“.org 0x7c00”。

我还编写了一个简单的引导加载程序代码。我使用的是“.org 0”,但我可以在不破坏功能的情况下删除它。我的代码是这样构建的:

all:

    i686-elf-as -o boot.o boot.S
    i686-elf-ld --oformat=binary -Ttext=0x0 -o boot.bin boot.o

I also very confused about it. It looks like it depends on your code and link arguments. If you look at the boot.S in grub2, it has no ".org 0" or ".org 0x7c00".

I also wrote a simple bootloader code. What I use is ".org 0", but I can remove it without breaking the function. My code is build like this:

all:

    i686-elf-as -o boot.o boot.S
    i686-elf-ld --oformat=binary -Ttext=0x0 -o boot.bin boot.o
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文