1

我正在使用 NASM 来组装我的汇编代码。我组装的代码如下所示:

[BITS 32]
[ORG 0]
  jmp 07c0h:start

  testvar db 0, 0, 0, 0, 0, 0, 4, 8, 15, 16, 23, 42

start:
  mov byte [testvar], 47

  hang:
    jmp hang

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

我在另一段代码中遇到了问题,我注意到我无法修改内存,所以我编写了这段代码来测试是否确实如此。它是!我将汇编的机器代码复制到软盘的第一个扇区,程序运行(我使用了 MS VirtualPC)。我检查了分配给 Virtual PC 的 RAM 内存并搜索了数字 4 8 15 16 23 42,这样我就可以找到二进制代码的复制位置。数据的第一个字节未被触及。为什么会这样?

4

4 回答 4

4

简单的答案是相同的代码组装成 32 位与组装成 16 位的不同。引导扇区代码(和所有加载的代码)在 16 位实模式下运行,直到切换 CPU 模式。

令人高兴的答案是清单显示了差异。

                                                [BITS 16]
0000000C: C6 06 00 00 2F                          mov BYTE [testvar], 47

与 32 位相同的代码

                                                [BITS 32]
0000000C: C6 05 00 00 00 00 2F                    mov BYTE [testvar], 47

以 16 位运行时的等效代码

                                                [BITS 16]
0000000C: C6 05 00                                mov BYTE [di], 0
0000000F: 00 00                                   add [bx+si], al
00000011: 00 2F                                   add [bx], ch
于 2010-09-08T08:45:59.393 回答
2

在源文件中设置“BITS 32”只会影响汇编器吐出的操作码。

要执行 32 位代码,您需要将处理器模式更改为 32 位保护模式。通常,当您移动到第一个玩具引导扇区之外时,您将分多个步骤进行内核加载。首先是 16 位引导扇区,具有大小限制。这会加载一个 16 位引导加载程序,进而可以设置保护模式。一些设计将这个 16 位部分保持最小,并进一步使用 32 位引导加载程序来加载内核,其他设计直接从 16 位引导加载程序加载内核。

我建议你看看http://wiki.osdev.org/Main_Pagehttp://www.asmcommunity.net/http://board.flatassembler.net/ :)

于 2010-09-08T19:52:18.310 回答
1

除了引导加载程序代码错误之外,还有一个问题bits 32是您没有设置ds任何内容,因此它将保留最后放入的任何 ROM-BIOS。您希望mov ax, 7C0h\mov ds, ax解决该问题(使用时org 0)。

于 2019-08-28T21:07:49.267 回答
0

我的理解是 PC 兼容机器都以 16 位模式启动(出于兼容性原因)。所以在我看来,您需要从 [BITS 16] 开始,即使第一条指令是跳转到 32 位模式并且紧随其后的是 [BITS 32]。请参阅NASM:混合 16 位和 32 位代码

我对软盘启动过程有点模糊。您确定代码位于实际执行的位置吗?是否可以单步执行该代码?

于 2010-09-08T04:50:15.787 回答