【问题标题】:Strange memory layout when creating constants in NASM在 NASM 中创建常量时出现奇怪的内存布局
【发布时间】:2012-01-06 05:50:40
【问题描述】:

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

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

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

【问题讨论】:

    标签: assembly nasm


    【解决方案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)并在之前使用 CLD 清除 FLAGS.DF LODSB.

    【讨论】:

    • 问题似乎正是你所说的。执行从数据开始。我将它移到引导扇区签名之前的文件底部,现在看起来很好。谢谢。
    猜你喜欢
    • 2014-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-13
    相关资源
    最近更新 更多