Memory Can';t使用32位汇编程序修改内存

Memory Can';t使用32位汇编程序修改内存,memory,assembly,x86,32-bit,nasm,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 我在另一段代码中遇到了问题,我注意到我无法修改内存,所以我编写了这段代码来测试

我正在使用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)。我检查分配给虚拟PC的RAM内存,搜索数字4 8 15 16 23 42,以便找到二进制代码复制的位置。未触及数据的第一个字节。为什么会这样?

我的理解是,与PC兼容的机器都以16位模式启动(出于兼容性原因)。 因此,在我看来,您需要以[BITS 16]开始,即使第一条指令是跳转到32位模式,并且紧接着是[BITS 32]。 看

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

我的理解是,与PC兼容的机器都以16位模式启动(出于兼容性原因)。 因此,在我看来,您需要以[BITS 16]开始,即使第一条指令是跳转到32位模式,并且紧接着是[BITS 32]。 看

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

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

简单的答案是,组装为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
在源文件中设置“32位”只会影响汇编程序输出的操作码

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

我建议您看看,并且:)

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

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


我建议您看一下,并且:)

除了引导加载程序代码的
位32
错误之外,还有一个问题是您没有将
ds
设置为任何值,因此它将保留最后放入其中的任何ROM-BIOS。您希望
mov-ax,7C0h
\
mov-ds,ax
来解决这个问题(当使用
org0
时)。

除了引导加载程序代码的
位32
错误之外,还有一个问题是您没有将
ds
设置为任何值,因此它将保留上次放入其中的任何ROM-BIOS。您需要
mov-ax,7C0h
\
mov-ds,ax
来修复此问题(在使用
org-0
时)。

您使用的是哪个O/S?您如何知道您的汇编代码正在加载和运行?你能用调试器一步完成它吗?在哪个地址加载?我使用的是Windows XP。我知道代码是运行的,因为如果我省略“[BITS 32]”,它可以正常工作。(为什么不加载呢?)。我该如何调试它呢?一点语言挑剔一个汇编器是一个汇编程序源代码的程序:)你在使用哪个O/S?您如何知道您的汇编代码正在加载和运行?你能用调试器一步完成它吗?在哪个地址加载?我使用的是Windows XP。我知道代码是运行的,因为如果我省略“[BITS 32]”,它可以正常工作。(为什么不加载呢?)。我该如何调试它呢?一点语言挑剔汇编程序是一个汇编汇编程序源代码的程序:)那么你是说如果我从16位引导扇区加载一个32位代码并跳转到它,32位代码将正常工作,而引导扇区本身是32位的就不会了?不。首先,无论你正在加载什么,都必须更改为32位模式。那么你是说,如果我从我的16位引导扇区加载32位代码并跳转到它,32位代码将正常工作,而引导扇区本身是32位的,则不会。不。首先,无论加载什么,都必须更改为32位模式。引导扇区始终加载到物理地址0x7C00,但并非所有BIOSE都同意用于引用此地址的CS:IP(请记住16位realmode寻址的古怪方式:seg*16+ofs)。引导扇区始终加载到物理地址0x7C00,但并非所有BIOS都同意用于引用此地址的CS:IP(请记住16位realmode add的古怪方式)