考虑部分引导加载程序的以下汇编程序代码:
bits 16
org 0x7C00
msg_init db 'Initializing...', 0Ah, 0Dh, 0
msg_completed db 'Completed', 0Ah, 0Dh, 0
jmp start
start:
xor ax, ax
mov ds, ax
mov es, ax
mov si, msg_init
call print
mov si, msg_completed
call print
mov al, '*'
mov bx, 0
mov ah, 0Eh
int 10h
cli
hlt
print:
lodsb ; al = [ds:si] - char to write
or al, al ; set zero flag if al=0
jz return ; jump to return if zero flag set
mov bx, 0 ; bh = page #, bl = color
mov ah, 0Eh ; function = teletype output
int 10h ; video interrupt
jmp print ; print next char if not zero
return:
ret ; return
times 510-($-$$) db 0
dw 0xAA55
内存布局如下所示:
0000: 49 6e 69 74 69 61 6c 69-7a 69 6e 67 2e 2e 2e 0a Initializing....
0010: 0d 00 43 6f 6d 70 6c 65-74 65 64 0a 0d 00 e9 00 ..Completed.....
0020: 00 31 c0 8e d8 8e c0 be-00 7c e8 11 00 be 12 7c .1.......|.....|
0030: e8 0b 00 b0 2a bb 00 00-b4 0e cd 10 fa f4 ac 08 ....*...........
0040: c0 74 09 bb 00 00 b4 0e-cd 10 eb f2 c3 00 00 00 .t..............
当我将msg_completed
常量更改为“已启用”,即msg_completed db 'Enabled', 0Ah, 0Dh, 0
时,内存布局更改为:
0000: 00 f0 e3 fe 00 00 2e 0a-00 00 15 7c 00 00 57 2a ...........|..W*
0010: 0d 00 45 6e 61 62 6c 65-64 0a 0d 00 e9 00 00 31 ..Enabled......1
0020: c0 8e d8 8e c0 be 00 7c-e8 11 00 be 12 7c e8 0b .......|.....|..
0030: 00 b0 2a bb 00 00 b4 0e-cd 10 fa f4 ac 08 c0 74 ..*............t
0040: 09 bb 00 00 b4 0e cd 10-eb f2 c3 00 00 00 00 00 ................
似乎覆盖了前几个字节。有什么想法吗?
答案 0 :(得分:1)
我没有观察到这种行为(在Windows XP上尝试过“在2003年6月13日编译的版本0.98.36”和“在2011年7月15日编译的版本2.09.10”)。所有4个二进制文件都有“初始化”。
你确定你没有改变别的吗?第二种情况下的二进制文件是NASM的输出,而不是你从媒体上读回的内容?
顺便说一下,你的代码无法运行。 CPU将从db 'Initializing...', 0Ah, 0Dh, 0
开始执行引导扇区。这是数据,而不是代码。
此外,确保代码中的CS=0
和IP>=0x7C00
早期(某些BIOS跳转到0x7C0:0
而不是0:0x7C00
)并清除{是一件好事在FLAGS.DF
之前CLD
{1}}。{/}