NASM 指令序列

NASM instruction sequence

https://github.com/cfenollosa/os-tutorial/tree/master/05-bootsector-functions-strings学习,我一直在尝试编写自己的引导扇区。

我目前正在尝试打印给定的字符串。

这是我的两个文件:

boot_main.asm

[org 0x7c00]

mov bx, hello
call print
jmp $

hello db 'HI', 0

%include "boot_print.asm"

times 510 - ($ - $$) db 0
dw 0xaa55

boot_print.asm

print:
    pusha

start:
    mov al, [bx]
    cmp al, 0
    je done

    mov ah, 0x0e
    int 0x10

    add bx, 1
    jmp start

done:
    popa
    ret

print_nl:
    pusha
    mov ah, 0x0e
    mov al, 0x0a
    int 0x10
    mov al, 0x0d
    int 0x10

    jmp done

现在这完美地工作并在屏幕上打印 "HI"。但是如果我把指令 hello db 'HI', 0 移到开头。即

boot_main.asm

[org 0x7c00]

hello db 'HI', 0

mov bx, hello
call print
jmp $

%include "boot_print.asm"

times 510 - ($ - $$) db 0
dw 0xaa55

这根本无法打印任何内容。我试图了解两者之间的区别。有帮助吗?

汇编程序根据您在源文件中写入的位置将内容放入内存。如果你把它放在开头,在 org 指令之后,HI[=12=] 字符串将被放置在那里,而 CPU 将尝试 运行 它就像它是代码(做无意义的事情并可能出错)。

相反,在原始代码中,字符串位于 jmp $ 之后,它被安全地存储在指令指针永远不会到达的位置。

如果您修改代码使 CPU 回避字符串,您将看到它再次开始工作:

[org 0x7c00]
    jmp real_start
    hello db 'HI', 0
real_start:
    mov bx, hello
    call print
    jmp $
    %include "boot_print.asm"
    times 510 - ($ - $$) db 0
    dw 0xaa55

同样,如果您认为 db 对字符串没有任何神奇作用,它只是在您写入输出二进制文件的位置输出任意字节,那么这一点就很明显了。如果您将它们写在执行路径中,CPU 将 运行 覆盖它们,如果您告诉 CPU 绕过它们,它会避开它们。