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跳过它们,它将避免它们。
你的例子,与sidestep锦上添花,美丽,谢谢! :) –
@KarthikNayak:很高兴帮助!有趣的是,当生成与位置无关的代码时,和/或当您的数据很小但不符合立即数,但仍然可以从中受益时,实际上将其用于“现实生活中”已经在使用它的寒冷中缓存。 –
关闭主题,你能解释你的个人资料中的笑话吗? –