I am writing a little bootsector for learning purpose.
Here is boot.S
movw $0xB800, %ax /* 0xB000 is the text screen video memory */
movw %ax, %es /* set it as the %es segment */
movb label, %al
movb %al, %es:0x0 /* screen = 'A' */
movb $0x07, %es:0x1 /* white on black */
and here is the Makefile I use to compile it to a raw binary file
as $< -o boot.o
ld --oformat binary -Ttext 0x7c00 boot.o -o hdd.img
I face the problem that the label is not relatively referenced: when loading the byte 'A', it uses the absolute address, say 0x7c14).
So I cannot relocate this bootsector at runtime (for example by copying it further in memory). It would be better if the label was simply referenced trough an offset from the current instruction.
Is it possible to do this ?
Best How To :
Of course it is possible to relocate strings.
First of all, your
-Ttext 0x7C00 is correct. Do not change it. At the beginning of your bootloader you should zero the segment registers (
mov $0, %ax // xor %ax, %ax would be more space efficient
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
mov %ax, %ss
Next, you should set up a stack. Read: osdev wiki about stacks
Now to your question: It is usual to address strings using segmentation in the form of
%ds:%si. When relocating the bootloader, just change
Assuming you call your string
mov $label, %si // Always prefix a label address with a $
You can get a character from a string using the
lodsb instruction (LOaD String Byte, which automatically increments
%si for you:
lodsb // Character is stored in `%al` now
Another recommendation is not to address the video memory manually. Use BIOS Interrupt 0x10.
Good luck with your bootloader!