为什么这个引导加载程序代码不起作用?
我的期望是它打印一个字符串,但什么也没有打印出来。 当我把绳子变短时,有时会起作用,当我再次把绳子变长时,有时会起作用。
我不知道为什么这不起作用。
有人可以帮助我吗? 谢谢。
我使用的汇编代码是:
(Emacs 23、Ubuntu 10.10、nasm、VirtualBox OSE)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
org 0x7c00
bits 16
str:
db "Some say the world will end in fire",10,13
db "Some say in ice",10,13
db "From what I've tasted of desire",10,13
db "I hold with those who favor fire",10,13
db "But if I had to perish twice,",10,13
db "I think I know enough of hate",10,13
db "To say that for destruction ice",10,13
db "is also great and would suffice."
db "Robert Frost - Fire and Ice"
db 0
start:
xor ax,ax
mov ds,ax
mov es,ax
mov si, str
xor bx,bx
mov ah, 0x0e
print:
lodsb ;al = current char
cmp al, 0
je end
int 0x10
jmp print
end:
cli
hlt
times 510 - ($-$$) db 0
dw 0xAA55
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
My expectation is that it prints a string, but nothing is printed out.
When I make the string shorter, it sometimes works, and when I make them longer again, it works sometimes.
I don't know why this isn't working.
Could somebody help me?
Thanks.
The assembly code I'm using is:
(Emacs 23, Ubuntu 10.10, nasm, VirtualBox OSE)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
org 0x7c00
bits 16
str:
db "Some say the world will end in fire",10,13
db "Some say in ice",10,13
db "From what I've tasted of desire",10,13
db "I hold with those who favor fire",10,13
db "But if I had to perish twice,",10,13
db "I think I know enough of hate",10,13
db "To say that for destruction ice",10,13
db "is also great and would suffice."
db "Robert Frost - Fire and Ice"
db 0
start:
xor ax,ax
mov ds,ax
mov es,ax
mov si, str
xor bx,bx
mov ah, 0x0e
print:
lodsb ;al = current char
cmp al, 0
je end
int 0x10
jmp print
end:
cli
hlt
times 510 - ($-$) db 0
dw 0xAA55
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
因为它从
7c00
的指令开始执行代码。不幸的是,这就是你的绳子所在。您应该在该字符串前面加上
jmp
指令,以便它跳转到start
。这通常是一个短跳转
EB xx
,后跟一个NOP90
。某些 BIOS 可能坚持采用这种形式,尽管这对处理器来说并不重要。换句话说,您需要寻找类似的内容:
请记住,短跳转的距离是有限的,大约为+/-128字节,因此您的字符串大小必然受到限制。如果您的 BIOS 不需要
EB xx 90
格式,您只需进行常规跳转即可。您可以尝试的另一件事是将整个字符串移至
hlt
指令之后:但是,这又取决于您的 BIOS 是否需要
jmp/nop
组合开始。Because it starts executing code right at the instruction at
7c00
. That, unfortunately is where you have your string.You should precede that string with a
jmp
instruction so that it jumps tostart
.This is usually a short jump
EB xx
followed by a NOP90
. Some BIOS' may insist on that being of this form even though it doesn't really matter to the processor.In other words, you'd be looking for something like:
Just keep in mind that the short jump is limited as to what distance it can go, roughly +/-128 bytes, so your string size will be necessarily limited by that. If your BIOS doesn't require the
EB xx 90
format, you can just do a regular jump.The other thing you could try is to move the entire string to after the
hlt
instruction:but, again, this depends on your BIOS not requiring the
jmp/nop
combo at the start.验证 paxdiablo 和 Igor Skochinsky 是否正确的一个好方法是将文本字符串放入文件中,然后通过反汇编程序运行它。正确打印的较短字符串应该分解为不会造成任何损害的代码字符串。失败的较短字符串和较长的字符串将包含非法指令、跳转或调用指令,或者甚至在末尾有一个 2 或 3 字节指令,该指令会占用
"xor ax, ax"
指令位于代码开头。A good way to verify that paxdiablo and Igor Skochinsky are correct is to put the text string in a file, then run it thorough a disassembler. The shorter strings that print properly should disassemble into a code string that doesn't hurt anything. The shorter strings that fail, and the longer string will either include illegal instructions, jump or call instructions, or even just have a 2- or 3-byte instruction at the end that eats up the opcode for the
"xor ax,ax"
instruction at the beginning of your code.