0

I am trying to write a simply bootloader in assembler. The bootloader copies sector 2 from a floppy to address 0x5000 (segment 0x500, offset 0x0), jumps to the segment and prints a message.

However, when I change the segment address to 0x1000, the message does not get printed anymore. I suspect the org 0x10000 instruction has a problem, which might be related to segmentation. I tried org 0x1000:0 too, but the message won't be printed.


Here is my bootloader code, which gets written to the first sector of the floppy:

[BITS 16]
org 0x7C00

start:
    mov ah, 0x02 ; Read sectors from drive
    mov al, 1    ; Read 1 sector
    mov ch, 0    ; Cylinder 0
    mov cl, 2    ; Sector 2
    mov dh, 0    ; Head 0

    mov bx, sect2dest;
    mov es, bx
    mov bx, 0x0

    int 0x13
    jmp sect2dest:0;

data:
    sect2dest equ 0x500

The magic identifier in the end is written by a custom linking script, so don't worry about that.


Here is my sector two, which should print a message:

[BITS 16]
org 0x5000

sect2:
        mov ah, 0x13
        mov al, 1
        mov bl, 0x17
        mov cx, msg_len
        mov dh, 0
        mov dl, 0
        mov bh, 0

        mov bp, 0
        mov es, bp
        mov bp, msg


        int 0x10

        jmp $

msg db 13,10,"Hello, World!"
msg_len equ $ - msg

As mentioned above, when I try writing sector 2 to any address larger than 0xFFFF, the message doesn't get printed.

MechMK1
  • 3,278
  • 7
  • 37
  • 55

1 Answers1

2

Consider that bp is 16 bit, so if you use an ORG of 10000h any offset won't fit in it.
I was expecting the assembler to raise a warning but a quick test shown otherwise.

Remember also that generally is best to avoid challenging the BIOS, thought I don't know how it is actually handled, I would avoid to print a string that strides two segments.
Since you are putting zero in es, make sure that the ORG is at most 10000h-[msg_len], so that the whole string is reachable within es.

Margaret Bloom
  • 41,768
  • 5
  • 78
  • 124
  • I may be mistaken but I think when using `-f bin`, `ORG X` is more like `ORG X % 0x10000`. Probably why you don't see a warning. However if you were to use `-f elf` (remove the ORG directive from asm file), then use a linker like _LD_ to link (and then generate a binary file) with an origin >= 0x10000 then the linker should warn you with a relocation error that you're trying to place a larger value than can fit into 16-bit target. – Michael Petch Apr 02 '16 at 20:42
  • And I meant `more like ORG X % 0x10000` when the target is 16-bit code. – Michael Petch Apr 02 '16 at 20:50