NASM指令序列

问题描述:

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

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

这些是我的两个文件:

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\0字符串将被放置在那里,并且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跳过它们,它将避免它们。

+1

你的例子,与sidestep锦上添花,美丽,谢谢! :) –

+1

@KarthikNayak:很高兴帮助!有趣的是,当生成与位置无关的代码时,和/或当您的数据很小但不符合立即数,但仍然可以从中受益时,实际上将其用于“现实生活中”已经在使用它的寒冷中缓存。 –

+0

关闭主题,你能解释你的个人资料中的笑话吗? –