【问题标题】:NASM initialized data in bin files seems not workingbin 文件中的 NASM 初始化数据似乎不起作用
【发布时间】:2016-06-29 05:24:41
【问题描述】:

我正在关注这本书 Writing a Simple Operating System — 来自 Nick Blundell 的 Scratch。我正在尝试执行第 21 页上的任务。我编写了一个简单的程序来测试初始化​​数据在 bin 文件中的工作方式。这是程序:

你好.asm

section .data

test:   db      'A'

section .text


        mov     ah,0x0e
        mov     al,[test]
        int     0x10

        jmp     $


        times   510-($-$$)      db      0
        dw      0xaa55

然后编译我这样做:

nasm hello.asm -f bin -o hello.bin

运行:

qemu-system-i386 hello.bin

问题是,预期的输出是字符'A',但我得到的是字符'S'

输出:

我猜test这个标签不能正常工作,但我不知道为什么

【问题讨论】:

  • 您需要将数据和文本部分合二为一。因此,将您的数据放在代码之后的文本部分(但在引导扇区签名之前)。如果您不这样做,您的代码部分将位于前 512 个字节中,并且数据将从第 513 个字节开始,这不是您想要的。由于您正在编写引导加载程序,因此您还需要指定一个正确的原点(即:org 0x7c00)。您还需要在开始时将 DS 寄存器设置为零。
  • 谢谢,它可以工作,我不需要将 DS 寄存器设置为零
  • 它之所以有效,是因为在许多环境中 DS 在执行引导加载程序之前通常为 0。这不能保证,因此最好明确地执行此操作。这可以通过 xor ax, ax mov ds, ax 之类的代码来完成。 xor ax, ax 是一种将寄存器(在本例中为 AX)设置为 0 的有效方法。
  • 是的,这样做是一个非常聪明的主意,再次感谢您

标签: assembly nasm qemu bootloader x86-16


【解决方案1】:

当使用带有-f bin 选项的NASM 时,.text 部分将出现在.data 部分之前的平面二进制文件中。因此,如果您编译代码,前 512 个字节将包含代码 (.text) 段,并且数据将出现在前 512 个字节之后。在像这样的引导加载程序中使用数据时,您希望数据位于前 512 个字节中。对于-f bin 和引导加载程序,最好的办法是删除.data 部分并将数据放在代码之后但引导加载程序签名之前。

您还应该使用 ORG 指令设置原点。引导加载程序在物理地址0x07c00 或CS:IP 0x0000:0x7c00(或其他等效segment offset pairs)处加载到内存中。最简单的方法是在代码顶部使用org 0x7c00。这将生成相对于 0x7c00 的偏移量和标签。 NASM 使用 -f bin 选项的默认值是使用原点 0x0000。

如果您使用org 0x7c00,您需要使用零值的DS段寄存器来正确访问内存中的数据。

您的代码可能如下所示:

org 0x7c00

section .text

        xor     ax,ax
        mov     ds,ax      ; DS = AX = 0
        mov     ah,0x0e
        mov     al,[test]
        int     0x10

        jmp     $

test:   db      'A'

        times   510-($-$$)      db      0
        dw      0xaa55

设置堆栈通常也是一个好主意。我有一个 Stackoverflow 答案,其中包含一些可能有用的 general bootloader tips

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-31
    • 1970-01-01
    • 1970-01-01
    • 2019-10-03
    相关资源
    最近更新 更多