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

发布于 2024-12-25 17:25:51 字数 1853 浏览 1 评论 0原文

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

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 常量更改为“Enabled”时,即 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 ................

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

Consider the following assembler code for a partial boot loader:

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   

The memory layout looks like this:

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

When I change the msg_completed constant to "Enabled" i.e. msg_completed db 'Enabled', 0Ah, 0Dh, 0 the memory layout changes to:

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

It seems the first few bytes are overwritten. Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

乱世争霸 2025-01-01 17:25:51

我没有观察到这种行为(在 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 code> 而不是 0:0x7C00),并在 LODSB 之前使用 CLD 清除 FLAGS.DF

I don't observe such behavior (tried "version 0.98.36 compiled on Jun 13 2003" and "version 2.09.10 compiled on Jul 15 2011" on Windows XP). "Initializing" is there in all 4 binaries.

Are you sure you didn't change anything else? And the binary in the second case is what NASM output, not what you read back from media?

Btw, your code isn't going to work. The CPU will start executing the boot sector from its very beginning, from db 'Initializing...', 0Ah, 0Dh, 0. That's data, not code.

Also, it would be a good thing to ensure that CS=0 and IP>=0x7C00 early in the code (some BIOSes jump to 0x7C0:0 instead of 0:0x7C00) and clear FLAGS.DF with CLD prior to LODSB.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文