views:

68

answers:

1

I am making a custom Operating System. I have two nasm files:

boot.asm:

[BITS 16]   ;tell the assembler that its a 16 bit code
[ORG 0x7C00]    ;Origin, tell the assembler that where the code will
;be in memory after it is been loaded

INT 0x13

JMP $       ;infinite loop

TIMES 510 - ($ - $$) db 0   ;fill the rest of sector with 0
DW 0xAA55           ; add boot signature

start.asm:

[BITS 16]
MOV AL, 72
CALL PrintCharacter
MOV AL, 101
CALL PrintCharacter
MOV AL, 108
CALL PrintCharacter
MOV AL, 108
CALL PrintCharacter
MOV AL, 111
CALL PrintCharacter
MOV AL, 44
CALL PrintCharacter
MOV AL, 32
CALL PrintCharacter

MOV AL, 87
CALL PrintCharacter
MOV AL, 111
CALL PrintCharacter
MOV AL, 114
CALL PrintCharacter
MOV AL, 108
CALL PrintCharacter
MOV AL, 100
CALL PrintCharacter
MOV AL, 33
CALL PrintCharacter

PrintCharacter: 
MOV AH, 0x0E
MOV BH, 0x00
MOV BL, 0x07
INT 0x10
RET

TIMES 512 - ($ - $$) db 0

I compile them into .bin files using these commands:

nasm boot.asm -f bin -o boot.bin
nasm start.asm -f bin -o start.bin

Then add them to a floppy image with these commands:

dd if=boot.bin bs=512 of=MyOS.img count=1
dd if=start.bin bs=512 of=MyOS.img count=2

When I boot from the floppy image in VirtualBox it shows 2 exclamation points instead of one and it doesn't even boot in QEmu (Q.app). I am new to Operating System development and so It would be nice if someone could tell me what I did wrong and give me some pointers on how to better set up my OS.

+4  A: 

Of course it prints two exclamation marks. Let's look at your code:

...
MOV AL, 33
CALL PrintCharacter    ;   |1
                       ;   |          ^     |4
PrintCharacter:        ;   v    |2    |     |
MOV AH, 0x0E           ;        |     |     |
MOV BH, 0x00           ;        |     |     |
MOV BL, 0x07           ;        |     |     |
INT 0x10               ;        |     |     |     5
RET                    ;        v     |3    v     ----> off to la-la land

Note: I added some arrows that illustrate how program execution proceeds.

The first two lines are responsible for printing the final ! after you've already output Hello, World. This is achieved via a call to your PrintCharacter sub-procedure. (arrows 1 and 2.) When PrintCharacter returns (arrow 3), your program simply continues straight onwards (arrow 4)... and the next line of code happens to be the beginning of PrintCharacter again. Since the AL register still contains 33 (ie. the ANSI code for !), another exclamation mark is printed.

Then, execution once again gets to RET, but this time, since you didn't actually CALL PrintCharacter, there is no defined place to return to, so it returns to... some undefined place, most probably (arrow 5). I suppose that's the instant where your OS stops continuing with the boot process.

Conclusion: After your code prints Hello, World!, it should do something else (it should at least stop), otherwise don't be surprised when you get undefined behaviour or a hang-up...

stakx
Thanks. I moved the infinite loop to start.asm and now it works. But it still can't boot with QEmu.
None
I don't know about QEMU. I can only guess: Perhaps your very first instruction (`INT 0x13h`) is the culprit. It could be that QEMU has the registers set differently on start-up, and the interrupt call does not do what you want. Try setting the registers explicitly (`AH = 02, AL = 01, ...`). Or QEMU isn't emulating your floppy drive and thus can't load your boot program. -- I must admit I don't understand what exactly you're doing in `boot.asm`. Shouldn't you be loading `start.asm` into memory and then *jump* to it?
stakx
When I put the main contents of start.asm in boot.asm it works fine.
None
Here's what you need to do then: Put code inside `boot.asm` that loads the sectors containing the code from `start.asm` into memory (e.g. through a call to an `INT 13h` function). Load it to some fixed address (specify that address with `ORG` in `start.asm`. Then, after that code has been loaded, make a far jump to it.
stakx