0

I'm starting learning how to make a Hello World in a Boot Loader in assembly. I have a problem because for some reason when I start of the floppy disk in "BOCHS" he can show me the Hello World. But when I try in "VMware" he identifies the Boot Loader but don't show anything.

In VMWare, I can already print a character on the screen but a entire string i can't.

[org 0x7c00]

mov bp, 0x7c00
mov sp, bp

mov bx, TestString
call PrintString

jmp $

PrintString:
    mov ah, 0x0e
    .Loop:
    cmp [bx], byte 0
    je .Exit
        mov al, [bx]
        int 0x10
        inc bx
        jmp .Loop
    .Exit:
    ret

TestString:
    db 'Hello World',0

times 510-($-$$) db 0

dw 0xaa55
Michael Petch
  • 46,082
  • 8
  • 107
  • 198
Tomás
  • 23
  • 4
  • 1
    Could be many different things. I don't really know VMWare. Maybe it expects a BPB? Maybe it boots your bootloader at `07c0:0000` instead of `0000:7c00` and you need to fix the segments? – fuz Jan 04 '23 at 12:16
  • Some tips here: https://stackoverflow.com/a/32705076/3857942 – Michael Petch Jan 04 '23 at 12:16
  • 2
    You forgot to initialize `ds`. You want `xor ax, ax; mov ds, ax`. – Jester Jan 04 '23 at 12:16
  • You also forgot to set `ss`. It's better to leave SS:SP unset than to set SP without also setting SS; you could potentially be putting your stack in the middle of your MBR bootloader if SS is a small integer like 5, so the first `int 0x10` overwrites the machine code for the loop. But yes, as Jester said you need to set DS to the value that works with the `org` you told NASM to assume. – Peter Cordes Jan 04 '23 at 12:34
  • I added mov ds, ax and it started working. But I'm completely new to writing code for a BIOS. What do DS and AX do? I'm viewing this series (https://www.youtube.com/watch?v=7LTB4aLI7r0) but it doesn't explain anything. I'm trying to start learning in this area, but I don't find many useful contents. I know a little about assembly, but at the BIOS level I don't understand. – Tomás Jan 04 '23 at 12:55
  • `DS` is a segment register that typically is used as the "data segment." When you do `mov al, [bx]` the CPU implicitly combines `DS` and `BX` to figure out what memory address to load from. If it's not set correctly, you'll end up loading something different than what you intended. The correct value for `ds` depends on what your program is (a bootloader, COM executable, EXE executable, etc.) and whatever your program is trying to do. As Jester said earlier the correct value is 0, and the most efficient way to make that happen is `xor ax, ax; mov ds, ax`. – puppydrum64 Jan 04 '23 at 14:03
  • Reason being is that the CPU isn't able to `mov` a constant value into `ds` or `es`, so you have to `mov` a register into them instead. – puppydrum64 Jan 04 '23 at 14:05

0 Answers0