引导加载程序无论如何都会在该地址加载它?为什么要将此指定给程序?
4 回答
ORG 伪指令的作用是告诉汇编器将此偏移量添加到提到的所有绝对地址。例如,如果您编写“MOV AX,my_string”并且 my_string 位于代码中的 1234 个字节,则汇编程序会生成“MOV AX,7c00h+1234”。不太常见的是,它也用于从给定的绝对地址计算相对地址(例如短跳转)。
你在这里别无选择。阅读这篇文章:
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。(即它 JMPs 到那个地址)
所以从启动开始,如果你想让 CPU 开始执行你的代码,它必须位于内存中的 0000:7c00。这部分代码是从硬盘的第一个扇区加载的——也是由硬件完成的。并且只有第一个扇区被加载,代码的其余部分必须由这个初始的“引导加载程序”加载。
更多信息在这里(关于硬盘启动扇区和 7c00 功能):
http://www.ata-atapi.com/hiwdos.html
http://www.ata-atapi.com/hiwmbr.html
请不要与 CPU 的启动模式混淆 - 它将获取并执行的第一条指令位于物理地址 0xfffffff0(参见第 9-5 页):
在这个阶段,它正在执行非易失性(这意味着您无法轻松对其重新编程,因此不属于引导加载程序的责任)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)
你没有给出这个问题的任何背景。但我会尝试给出某种形式的答案。
当程序加载到内存后执行时,程序必须位于某个地方,假设这是地址 7C00。处理器开始执行某处,在您的情况下很可能是 7C00。ORG 语句告诉汇编器以下指令的地址将出现在该地址处。
为什么不是0?好吧,您的处理器可能需要这些地址上的其他东西,即。中断向量。
您的处理器的数据表将为您提供有关其启动顺序的更多信息。
祝你好运。
从一个快速的好...
我也很困惑。看起来这取决于您的代码和链接参数。如果您查看 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