Bootloader ASM

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
Jhoozle
Posts: 3
Joined: Wed Sep 08, 2021 4:49 pm

Bootloader ASM

Post by Jhoozle »

Hello,

I'm new to assembly and trying to teach myself. I wrote a small Hello World bootloader from a tutorial I found on this site. My current toolchain is Win10, VS Code, and Nasm. DD to create the image and Rufus to burn it to a USB stick. That process works I've gotten text output. However I am trying to display a whole string and for some reason it only displays it partially. The string being Hello and all I get is Hel. Here's my code.


org 0x7C00

main:
mov ax, 0x0000
mov ds, ax

mov si, Message
call Print_String

jmp $

Print_String:
lodsb
or al, al
jz .return
mov ah, 0x0E
int 0x10
jmp Print_String

.return:
ret

Joe db 'Hello!', 0

times 510-($-$$) db 0
dw 0xAA55

In the process of trying to debug this I realized that no matter what string I put in it always stops at a lower case L. I also at one point had the following line.

Message db 'Hello!', 0
as
Message db 'Hello!', 13, 10, 0 ;
as well as
Message db 'Hello!', 0x80, 0x0A, 0;

If I understand correctly 13 is carriage return, 10 is Line Feed, and 0 is the null termination character. I don't know what 0x80 or 0x0A represent. I just used them because that's what was in the tutorial on the site.

Any help would be greatly appreciated. Thank you in advance.
Klakap
Member
Member
Posts: 297
Joined: Sat Mar 10, 2018 10:16 am

Re: Bootloader ASM

Post by Klakap »

Some BIOSes will assume that your bootloader has BPB and they will overwrite part of your code. This is probably this case. Solution is remain BPB space on start of code like this:

Code: Select all

main:
 jmp .code
 times 0x3E db 0
 .code:
User avatar
iansjack
Member
Member
Posts: 4703
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Bootloader ASM

Post by iansjack »

Also note that you should clear the DF flag before using lodsb.
User avatar
eekee
Member
Member
Posts: 891
Joined: Mon May 22, 2017 5:56 am
Location: Kerbin
Discord: eekee
Contact:

Re: Bootloader ASM

Post by eekee »

The code looks correct to me. I'd implement both Klakap's and iansjack's recommendations. iansjack's because the direction flag happens to be correct but could be changed by the BIOS, if I understand right. Klakap's because there's no chance that or...jz would jump on anything other than zero. Corruption of the string looks like the most likely thing.


About testing, I would try to avoid saying "it stops on an l" unless I'd tried moving the ls, perhaps by changing "Hello" to "Honaly" or something. I say "try" because I don't find it easy; I have a real problem with jumping to conclusions when I've been coding a bit too hard or too long. A bug comes up and I think I know exactly what it is when a little bit of reasoning would show I don't. I think this happens to everyone sooner or later, I hope you don't get it as badly as I do.
Kaph — a modular OS intended to be easy and fun to administer and code for.
"May wisdom, fun, and the greater good shine forth in all your work." — Leo Brodie
Jhoozle
Posts: 3
Joined: Wed Sep 08, 2021 4:49 pm

Re: Bootloader ASM

Post by Jhoozle »

Thank you all for you replies. I managed to get it working before my question was put up after review, by going through another thread about the BIOS corrupting the BPB. and it looks like I ended up clearing the direction flag on accident anyways. I'll post my new code below.

Code: Select all

BITS 16
org 0x7C00

jmp 0x0000:Boot

times 0x5a db 0

Boot:
    cli
    xor ax, ax 
    mov ds, ax
    mov es, ax
    mov ss, ax     
    mov sp, 0x9000
    cld
    sti

    mov si, Msg
    call Print_String

    jmp $

Print_String:
    lodsb

    or al, al
    jz .done

    mov ah, 0x0E
    int 0x10

    jmp Print_String

.done:
    ret

Msg: db "Hello!", 0x0D, 0x0A, 0

times 510-($-$$) db 0
dw 0xAA55
I still have a few questions though.

First the padding. Klakap you indicate the padding should be "times 0x3E db 0" In the thread I found on this topic the suggestion was "times 0x5A db 0" is the amount arbitrary?

This may not be an easy question to answer but this code works fine on my custom built PC's, however I have two Dell Optiplex's here and both register the USB drive as being inserted but says it's not a valid boot drive. The bios is set to Legacy not UEFI and the only boot device selected is the USB stick any thoughts as to why this is? Is there something special about booting with a Dell BIOS?

Thanks all.
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: Bootloader ASM

Post by Octocontrabass »

Jhoozle wrote:First the padding. Klakap you indicate the padding should be "times 0x3E db 0" In the thread I found on this topic the suggestion was "times 0x5A db 0" is the amount arbitrary?
The amount is enough to ensure none of your code ends up inside the BPB. The two suggested amounts are for different BPB sizes; 0x3E for FAT12 or FAT16 and 0x5A for FAT32. I think you could get away with less; you only need to avoid the geometry.
Jhoozle wrote:This may not be an easy question to answer but this code works fine on my custom built PC's, however I have two Dell Optiplex's here and both register the USB drive as being inserted but says it's not a valid boot drive. The bios is set to Legacy not UEFI and the only boot device selected is the USB stick any thoughts as to why this is? Is there something special about booting with a Dell BIOS?
Some BIOSes will reject your drive if it's not partitioned appropriately. You don't have a partition table in your code, and I don't think Rufus will add one. There's an entire page on the wiki dedicated to this topic, although some of the advice may be outdated.
Jhoozle
Posts: 3
Joined: Wed Sep 08, 2021 4:49 pm

Re: Bootloader ASM

Post by Jhoozle »

Octocontrabass wrote:
Jhoozle wrote:First the padding. Klakap you indicate the padding should be "times 0x3E db 0" In the thread I found on this topic the suggestion was "times 0x5A db 0" is the amount arbitrary?
The amount is enough to ensure none of your code ends up inside the BPB. The two suggested amounts are for different BPB sizes; 0x3E for FAT12 or FAT16 and 0x5A for FAT32. I think you could get away with less; you only need to avoid the geometry.
Jhoozle wrote:This may not be an easy question to answer but this code works fine on my custom built PC's, however I have two Dell Optiplex's here and both register the USB drive as being inserted but says it's not a valid boot drive. The bios is set to Legacy not UEFI and the only boot device selected is the USB stick any thoughts as to why this is? Is there something special about booting with a Dell BIOS?
Some BIOSes will reject your drive if it's not partitioned appropriately. You don't have a partition table in your code, and I don't think Rufus will add one. There's an entire page on the wiki dedicated to this topic, although some of the advice may be outdated.
Thank you, sir. I'll give that a read.
Post Reply