无法使用 32 位汇编程序修改内存

发布于 2024-09-18 03:30:29 字数 438 浏览 11 评论 0 原文

我正在使用 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,这样我就可以找到二进制代码被复制的位置。数据的第一个字节未被触及。为什么会这样呢?

I am using NASM to assemble my assembler code. The code I assembled looks like this:

[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

I had problems with another piece of code, I noticed that I couldn't modify memory, so I wrote this piece of code to test if that was actually the case. It was! I copied the assembled machine code to the first sector of a floppy, the program ran (I used MS VirtualPC). I checked RAM memory assigned to Virtual PC and searched for numbers 4 8 15 16 23 42, so that I could find where the binary code was copied. The first byte of the data was not touched. Why is it so?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

旧梦荧光笔 2024-09-25 03:30:29

简单的答案是,相同的代码汇编为 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

The simple answer is that the same code assembled as 32 bit is different than that assembled as 16 bit. Boot sector code (and all loaded code) is run in 16 bit real mode until the CPU mode is switched.

The happy answer is a listing shows the difference.

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

The same code as 32 bit

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

The equivalent code when run as 16 bit

                                                [BITS 16]
0000000C: C6 05 00                                mov BYTE [di], 0
0000000F: 00 00                                   add [bx+si], al
00000011: 00 2F                                   add [bx], ch
野稚 2024-09-25 03:30:29

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

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

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

Setting "BITS 32" in your source file only affects the opcodes the assembler spits out.

To execute 32bit code, you'll need to change the processor mode to, surprise surprise, 32bit protected mode. Typically, when moving a bit beyond your very first toy bootsector, you'll do your kernel loading in multiple steps. First, the 16bit bootsector, with all it's size constraints. This loads a 16bit bootloader, which in turn can set up protected mode. Some designs keep this 16bit part minimal and further uses a 32bit bootloader for loading the kernel, other designs load the kernel directly from the 16bit bootloader.

I suggest you take a look at http://wiki.osdev.org/Main_Page , http://www.asmcommunity.net/ and http://board.flatassembler.net/ :)

网名女生简单气质 2024-09-25 03:30:29

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

An issue other than bits 32 being wrong for boot loader code is that you do not set ds to anything, so it will retain whatever the ROM-BIOS put into it last. You want mov ax, 7C0h \ mov ds, ax to fix that (when using org 0).

我是有多爱你 2024-09-25 03:30:29

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

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

My understanding is that PC compatible machines all start in 16 bit mode (for compatibility reasons).
So it seems to me that you need to begin with [BITS 16], even if the first instruction is a jump to to 32 bit mode and is immediately followed by [BITS 32].
See NASM: Mixing 16 and 32 Bit Code.

I'm a little fuzzy on the floppy boot process.
Are you sure the code is located where it will actually be executed?
Is it possible to single-step through that code?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文