0

i'm trying to write a boot sector that displays a small message on boot, but running the following on QEMU produces malformed text and any string with more than 5 characters doesn't show at all. here's the code i assembled with NASM to a raw .bin file

[bits 16]
[org 0x7c00]
start:
        xor ax,ax
        mov ds,ax
        mov es,ax
        mov bx,0x8000

        mov ax,0x13
        int 0x10

        mov ah,02
        int 0x10

        mov ah,0x02
        mov bh,0x00
        mov dh,0x12
        mov dl,0x03
        int 0x10

        mov si , welcome
        welcome db "hello",13,0
        call RainbowPrint
RainbowPrint:
        mov bl,1
        mov ah, 0x0E
        .repeat_next_char:
                lodsb
                cmp al, 0
                je .done_print
                add bl,6
                int 0x10
                jmp .repeat_next_char

        .done_print:
                ret
times (510 - ($ - $$)) db 0x00
dw 0xAA55

EDIT : here's an image showing the program running in qemu

  • Define _"malformed text"_. What does it look like, and what did you expect it to look like? – Michael Apr 28 '20 at 15:36
  • 1
    One suspicious thing is that you've placed your string in the middle of your code. You should move it out of the execution path, e.g. right after the `ret` or the `jmp .repeat_next_char`. – Michael Apr 28 '20 at 16:26
  • sounds like that's it , just moving the string declaration under `CALL RainbowPrint` works fine ,my guess is the opcodes somehow overwrite it, still working on resetting cursor position though. – blue eagle Apr 30 '20 at 13:32
  • Does this answer your question? [Segmentation fault when using DB (define byte) inside a function](https://stackoverflow.com/questions/55642600/segmentation-fault-when-using-db-define-byte-inside-a-function) – Peter Cordes Apr 30 '20 at 13:37
  • 1
    The bytes from `db` don't get overwritten by opcodes, they're *treated as* opcodes. Assemble this version of your bootloader, then disassemble it with `ndisasm` to see how a CPU will see it. Or just single-step through your code in a debugger. (Attach GDB to qemu, or use BOCHS for its built-in debugger. Debugging asm without using a debugger is a waste of your time.) – Peter Cordes Apr 30 '20 at 13:40
  • You should also put an infinite loop or something else so that the code after `call RainbowPrint` doesn't fall into the function `RainbowPrint:` a second time potentially printing out more garbage. You could put an infinite loop with `jmp $` right after `call RainbowPrint` to effectively end your bootloader and prevent it from doing anything else. – Michael Petch Apr 30 '20 at 13:41

1 Answers1

0

You seem to overlapping your char_stream

welcome db "hello", 13, 0

I reviewed your code and came up with the following that has a clear display of your specific char_stream

[bits 16]
[org 0x7c00]
start:
    xor ax,ax
    mov ds,ax
    mov es,ax
    mov bx,0x8000

    mov ax,0x13
    int 0x10

    mov ah,02
    int 0x10

    mov ah,0x02
    mov bh,0x00
    mov dh,0x12
    mov dl,0x03
    int 0x10

    mov si , welcome
    ; Your [welcome] stream was here before...
    call RainbowPrint

;***********
; Don't mind this area... just a simple key detection and reboot method...
xor ax, ax
int 0x16
xor ax, ax
int 0x19
;***********

; Move your stream away from operatable code areas:
welcome db  "Hello, World!", 0x0D, 0x0A, 0x00

RainbowPrint:
    mov bl,1
    mov ah, 0x0E
    .repeat_next_char:
            lodsb
            cmp al, 0
            je .done_print
            add bl,6
            int 0x10
            jmp .repeat_next_char

    .done_print:
            ret
times (510 - ($ - $$)) db 0x00
dw 0xAA55

The prefered text stream