在NASM中创建常量时奇怪的内存布局

时间:2012-01-06 05:50:41

标签: assembly nasm

考虑部分引导加载程序的以下汇编程序代码:

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 ................

似乎覆盖了前几个字节。有什么想法吗?

1 个答案:

答案 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=0IP>=0x7C00早期(某些BIOS跳转到0x7C0:0而不是0:0x7C00)并清除{是一件好事在FLAGS.DF之前CLD {1}}。{/}