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

时间:2010-09-07 23:55:20

标签: memory assembly x86 32-bit nasm

我正在使用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 个答案:

答案 0 :(得分:5)

简单的答案是,组装为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

答案 1 :(得分:2)

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

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

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

答案 2 :(得分:1)

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

答案 3 :(得分:0)

我的理解是PC兼容机器都以16位模式启动(出于兼容性原因)。 因此在我看来,你需要以[BITS 16]开头,即使第一条指令是跳转到32位模式,然后紧接着是[BITS 32]。 请参阅NASM: Mixing 16 and 32 Bit Code

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