2010-09-07 62 views
1

我正在使用NASM汇编我的汇编程序代码。我组装的代码看起来是这样的:无法使用32位汇编程序修改内存

[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,以便我可以找到二进制代码被复制的位置。数据的第一个字节没有被触及。为什么这样?

+0

?你怎么知道你的汇编代码正在被加载和运行?你能用调试器单步执行吗?它在什么地址加载? – ChrisW 2010-09-08 00:00:39

+0

我正在使用Windows XP。我知道代码已经运行,因为如果我省略“[BITS 32]”,它就可以正常工作。 (为什么它不会被加载?)它被加载到启动扇区正常加载的地方,达到7c00h。我怎么能调试它? – 2010-09-08 00:06:49

+0

一个挑剔*汇编程序*的语言是一个程序,它汇编* *程序集*源代码:) – snemarch 2010-09-08 19:47:28

回答

0

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

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

+0

引导程序总是加载到物理地址0x7C00,但并非所有的BIOS都同意CS:IP用于指代这个地址(记住古怪的方式16位实模式寻址工作:seg * 16 + ofs)。 – snemarch 2010-09-08 19:53:36

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 
+0

然后你是说如果我要从我的16位启动扇区加载一个32位代码并跳转到它,那32位代码将正常工作,而引导扇区本身是32位不会? – 2010-09-08 14:25:43

+0

不需要。首先,您正在加载的任何内容都必须更改为32位模式。 – 2010-09-29 15:33:57

2

设置在源文件中“位32”运行的等价代码只影响操作码汇编吐出来。

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

我建议你把/ S您使用的形成为O一看http://wiki.osdev.org/Main_Pagehttp://www.asmcommunity.net/http://board.flatassembler.net/ :)

+0

我已经去过osdev.org,感谢其他地址。 ;-) – 2010-09-12 04:38:37