【问题标题】:"times 510-($-$$) db 0" does not work“次 510-($-$$) db 0”不起作用
【发布时间】:2016-07-03 07:48:37
【问题描述】:

我正在学习引导扇区。我从 NASM 网站下载了 nasm-installer-x64.exe。我的操作系统是win7-64bit。当我运行以下代码时,它无法正常工作

mov ah, 0x0e;

mov al, the_secret;
int 0x10;

mov al, [the_secret];
int 0x10;

mov bx, [the_secret];
add bx, 0x7c00;
mov al, [bx];
int 0x10;

mov al, [0x7c1e];
int 0x10;

jmp $;

the_secret:;
    db 'X';

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

【问题讨论】:

  • 是什么让您认为times 510-($-$$) db 0 不起作用?对我来说似乎很好。也许您的引导加载程序还有其他问题?
  • 非常感谢。从我的 asm 代码生成的图像文件不正确。首先,它包含 526 个字节,应该是 512 个字节。其次,它以 0x5500 结束,应该是 0x55aa。我不知道为什么会这样……
  • 我发现,我上面描述的现象是由nasm编译的结果与写入我的图像文件的结果不同造成的。我使用命令nasm -f bin boot_sect.asm -o boot_sect.bin,对吗?
  • 没错。如果您查看我的答案的底部,我举了一个如何组装它的示例,这与我的建议相符。您使用什么命令将引导扇区放在磁盘上?
  • 如果您没有可用的 DD 命令,我推荐它作为一个有用的工具,您可以在 Windows 上使用它来构建磁盘映像。可以从这里下载:chrysocome.net/downloads/dd-0.6beta3.zip

标签: assembly nasm bootloader osdev x86-16


【解决方案1】:

我认为times 510-($-$$) db 0 没有任何问题。在我看来,您正在尝试找到访问变量 the_secret 的正确方法,然后将其显示到屏幕上。我将提供一种基于此尝试的最有希望的机制:

mov al, [the_secret];
int 0x10;

如果您正确设置 DS,请使用 org 0x7c00 设置原点并确保将 BH 设置为您要写入的页码(您想要0) 那么下面的代码应该可以工作:

[bits 16]          ; 16-Bit code
[org 0x7c00]       ; Set the origin point to 0x7c00

start:
    xor ax,ax      ; We want a segment of 0 for DS for this question
    mov ds,ax      ;     Set AX to appropriate segment value for your situation
    mov es,ax      ; In this case we'll default to ES=DS
    mov bx,0x8000  ; Stack segment can be any usable memory

    mov ss,bx      ; This places it with the top of the stack @ 0x80000.
    mov sp,ax      ; Set SP=0 so the bottom of stack will be @ 0x8FFFF

    cld            ; Set the direction flag to be positive direction

    mov ah, 0x0e
    mov al, [the_secret]  ; al = character from memory DS:[the_secret]
    xor bh, bh            ; bh = 0 = video page number
    int 0x10;

    jmp $

the_secret:;
    db 'X';

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

启动代码将 DS 设置为零,因为我们将原点设置为 0x7c00。引导加载程序加载到 0x0000:0x7c00(物理地址 0x07c00)。这确保访问变量the_secret 将正确完成。 mov al, [the_secret] 相当于说mov al, ds:[the_secret]。如果DS段寄存器设置不正确,原点设置不正确,内存访问将不会从正确的位置读取。

INT 0x10/AH=0x0E 需要设置页码。第一个视频显示页为0,BH要相应设置。

有关其他设置说明的更多信息,请参阅我的 StackOverflow 答案,其中包含 General Bootloader Tips

如果正确写入磁盘映像,我提供的代码应该在控制台上显示X


组装此代码并生成磁盘映像(在我的示例中为 720k 软盘):

nasm -f bin bootload.asm -o bootload.bin
dd if=/dev/zero of=disk.img bs=1024 count=720
dd if=bootload.bin of=disk.img bs=512 count=1 conv=notrunc

第一个命令将bootload.asm 组装成一个名为bootload.bin 的平面二进制文件。第二个命令产生一个大小为 1024 * 720(720kb 软盘)的零填充磁盘映像 (disk.img),最后一个命令将 512 字节的数据从bootload.bin 复制到磁盘映像的第一个扇区。 conv=notrunc 告诉 DD 在写入后不要截断文件。如果您不使用它,disk.img 将在引导扇区写入后长 512 个字节。

【讨论】:

  • 感谢您的详细解释。这对我帮助很大,真的。
  • 我最近成功运行了“内核”。看完之后,我对这段代码有了更多的了解。今天发现你提到bh是需要设置的,因为涉及到页码。但是,我实际上根本没有设置它。你能为我解释更多吗?什么是页码……
  • 我的回答提供了 Int 10h/ah=0eh 的信息链接:ctyme.com/intr/rb-0106.htm。 Ralf Brown 的中断列表已成为 BIOS/DOS 信息的标准。在链接中,您应该注意到它说 BH = page number 。您可能有不止一页的视频内存可供显示。第 0 页是系统引导时的默认设置。最好将此 INT 调用设置为 BH 为零,以确保写入默认页面。不这样做可能会导致文本不显示。页面数量有限,可能 BH 无效,因此默认为 0
  • 我明白了。非常感谢~
猜你喜欢
  • 1970-01-01
  • 2013-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多