Why doesn't this boot loader code work?
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 i开发者_Python百科n 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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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 to start
.
This is usually a short jump EB xx
followed by a NOP 90
. 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:
org 0x7c00
bits 16
realstart:
jmp short start
nop
str:
db "Some say the world will end in fire",10,13
:
db "Robert Frost - Fire and Ice"
db 0
start:
xor ax,ax
:
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:
org 0x7c00
bits 16
start:
xor ax,ax
:
end:
cli
hlt
str:
db "Some say the world will end in fire",10,13
:
db "Robert Frost - Fire and Ice"
db 0
but, again, this depends on your BIOS not requiring the jmp/nop
combo at the start.
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.
精彩评论