I'm writing this bootloader that just prints out some stuff on the screen. This is what I have so far in assembly:
.globl _start
.code16
_start:
movw $0x0003, %ax
int $0x10
movb $0x0e, %ah
movb $0x69, %al
int $0x10
movw $_header, %bx
movb %bl, %al
int $0x10
_header: .ascii "W\0"
.org 0x1FE
.byte 0x55
.byte 0xAA
So right now it prints ASCII 69 ("i"), but I want it to print the .ascii
declaration as well. Right now I only have it set to "W"
so I could find it easily in Objdump
. I can't seem to get access to that value (57). I can leal $_header, %edx
and such, but then I can't seem to access the value at %edx
.
I tried using lodsb
, but I can't seem to figure it out. I set %di
to 0x00, and set %si
to the address of _header
with leal %si, _header
but then my lodsb
followed by int 0x10
doesn't seem to print anything. Any ideas I'd appreciate.
Here:
movw $_header, %bx
movb %bl, %al
First, movb %bl, %al
isn't reading a byte from memory into al
, it's reading a byte from bl
. You want to change it to:
movb (%bx), %al
To get just one character out of _header
you could load that character from the memory into al
directly:
movb _header, %al
Secondly, and most importantly, it appears that you're making several assumptions:
cs
=0x7c0, ip
=0. It can be cs
=0, ip
=0x7c00 instead, but your code is expecting ip
=0 (I infer from the code that the assembler starts assembling it with the implicit .org 0
). You should make your code resilient to this second option. You can reload cs
and ip
to more suitable values with a jump instruction, something like this: jmp $0x7c0,$_next
and the corresponding label on the next line: _next:
.ds
=0x7c0. ds
isn't guaranteed to be set to any value you may want or need. You have to initialize it yourself.Finally, what happens after the last int $0x10
?
With the corrections your code should look something like this:
.globl _start
.code16
_start:
/* .org 0 is implied here! But the code may start with ip != 0. */
jmp $0x7c0,$_next
_next:
/* We have just ensured that cs=0x7c0,ip=$_next */
/* Let's now load data segment registers with proper values */
movw %cs, %ax
movw %ax, %ds
movw %ax, %es
movw $0x0003, %ax
int $0x10
movb $0x0e, %ah
movb $0x69, %al
int $0x10
movw $_header, %bx
movb (%bx), %al /* read into al a byte from memory at address from bx */
int $0x10
/* Halt execution, don't just execute whatever garbage is in memory */
/*after the end of the code. */
_halt:
hlt
jmp _halt
_header: .ascii "W\0"
.org 0x1FE
.byte 0x55
.byte 0xAA