4

**请注意,当我说启动程序时,我并不是指启动操作系统的程序。我的意思是,当您启动计算机并执行某些操作时运行的简单程序。

好吧,所以我对汇编/NASM 不是非常精通,但我认为我对它有足够的了解,可以编写简单的引导程序。

好吧,我认为我掌握得足够好。显然不是。

我尝试了一个在网上找到的简单引导程序。它运行良好(打印字母“A”)。然后我修改它以打印存储在内存中的字母。它失败了;它不是打印一个“A”,而是打印一个笑脸。(我发誓,电脑现在在嘲笑我。)

这是源文件中的代码:

[BITS 16]    ; We start up in 16-bit real mode
[ORG 0x7C00] ; We're booted into memory at this address. (Or so I'm told)

mov ah, 0x0E       ; Teletype command
mov bh, 0x00       ; Page number
mov bl, 0x07       ; Attributes (7 == white foreground, black background)
mov al, [testChar] ; Character to print; load it from the memory referenced by testChar.

int 0x10  ; Tell the BIOS to execute the teletype command.

jmp $  ; Infinite loop prevents us from going off and executing the other junk in memory

testChar db 65  ; This is the character we want to print. 'A'.

; The following code pads the rest of the outputted binary file
;   and concludes it with the bootloader signature so I don't have
;   to do so manually.
times 510-($-$$) db 0
dw 0xAA55

如果我将“ move al, [testChar] ”替换为“ move al, 65 ”,则字母“A”会正确打印。我尝试过移动内存声明,尝试了所有括号组合或 BITS 和 ORG 周围没有括号,并且尝试递增和递减 testChar(即 [testChar+1])。每次,它都会打印一个笑脸、一个反笑脸(当我增加 testChar 时),或者什么都不打印(当我将内存声明放在代码之前,可能是因为没有执行代码 =P)。我不能让这该死的东西工作。

现在,对于规范(因为它们可能是相关的):

  • 我正在运行带有 Intel Pentium II 处理器的 Dell Latitude CPi,因为这就是我要测试的全部内容(我没有用我的普通计算机测试汇编程序。见鬼。)。我很确定说处理器是 x86,因为我在上面运行了 Windows XP、Ubuntu 和 Arch Linux。

  • 我目前正在使用 NASM 在 Arch Linux 上编写和编译程序。

  • 引导程序从软盘运行

  • 我使用“ nasm -f bin FILENAME ”来编译代码。

  • 然后,我使用 AL 的“mtools”包中的“mformat”命令通过“ mformat -f 1440 -B BOOTPROGRAM A: ”将编译后的引导程序传输到软盘。

那么,这次我搞砸了什么?还是我的处理器/BIOS 有问题?

4

3 回答 3

3

DS 可能充满了一些垃圾值,所以只需执行以下操作:

push cs
pop ds

或者

mov ax, cs
mov ds, ax
mov es, ax

更好的是,不要相信 CS 并做:

xor ax, ax
mov ds, ax

请参阅此讨论:某些 BIOS 可能使用 07c0:0000 而不是传统的 0000:7c00,特别是在使用 ElTorito 从 CD-ROM 引导时。

于 2011-07-11T06:45:51.823 回答
0

我第一次运行时它运行良好!它打印“A”。使用命令 nasm [filename.asm] -o [filename.com] -l [filename.lst]

我使用了 nasm OSbad.asm -o OSbad.com 。使用 MagicISO 制作可启动映像文件 OSbad.iso 并使用 Windows 磁盘刻录机将其刻录到 DVD/RW。加载 Oracle VM 并创建一个具有 256 Mb RAM、CD/DVD、2GB 硬盘的新虚拟机。用 DVD 启动,它会在屏幕上打印“A”。

所以我猜你的程序正在运行。一定是你正在做的其他事情使它不起作用。

于 2013-06-27T09:38:04.127 回答
0

这将产生以下代码(只需在编译的代码上运行 objdump)。

00000000  B40E              mov ah,0xe
00000002  B700              mov bh,0x0
00000004  B307              mov bl,0x7
00000006  A00D7C            mov al,[0x7c0d]
00000009  CD10              int 0x10
0000000B  EBFE              jmp short 0xb
0000000D  41                inc cx ; this is actually your testChar
                                   ; ignore the opcode translation

现在,如果您位于 0x7C00,那么 [0x7c0d] 将是其中的最后一个字节(即 0x41 或 65,或 ASCII “A”)。但是,如果像其他贡献者之一 (ninjalj) 提到您有一些奇怪的 bios 错误,这意味着您不在 0x7C00,那么 [0x7c0d] 是任何人的猜测。

于 2011-07-12T14:57:53.190 回答