我正在使用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,这样我就可以找到二进制代码的复制位置。未触及数据的第一个字节。为什么会这样?
答案 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_Page,http://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。
我在软盘启动过程中有点模糊。 您确定代码位于实际执行的位置吗? 是否可以单步执行该代码?