As the title says, I'm trying to write a simple boot loader in assembly to help with my virtual machine monitor that I've tried to implement using the D programming language. Can anyone help me resolve the following error, nasm -f elf64 -o bootloader.o boot.asm
boot.asm:28: error: instruction not supported in 64-bit mode?
jmp eax is the instruction on line 28.
Here is the assembly code:
section .text align=1
start:
; Load the kernel code into memory
mov edx, 0x8000
mov dh, 0x02
mov dl, 0x80
mov ah, 0x02
int 0x13
jnc kernel_loaded
jmp error
kernel_loaded:
; Set the entry point for the kernel
mov eax, [0x8000 + 0x218]
mov ecx, [0x8000 + 0x21A]
mov edx, 0
add edx, ecx
add ecx, ecx
add edx, ecx
add ecx, ecx
add edx, ecx
add ecx, ecx
add edx, ecx
add ecx, ecx
add edx, ecx
add eax, edx
add eax, 0x8000
jmp eax
; Display "Loading complete." on the screen
mov ah, 0x00
mov al, 'L'
int 0x10
mov ah, 0x00
mov al, 'o'
int 0x10
mov ah, 0x00
mov al, 'a'
int 0x10
mov ah, 0x00
mov al, 'd'
int 0x10
mov ah, 0x00
mov al, 'i'
int 0x10
mov ah, 0x00
mov al, 'n'
int 0x10
mov ah, 0x00
mov al, 'g'
int 0x10
mov ah, 0x00
mov al, ' '
int 0x10
mov ah, 0x00
mov al, 'c'
int 0x10
mov ah, 0x00
mov al, 'o'
int 0x10
mov ah, 0x00
mov al, 'm'
int 0x10
mov ah, 0x00
mov al, 'p'
int 0x10
mov ah, 0x00
mov al, 'l'
int 0x10
mov ah, 0x00
mov al, 'e'
int 0x10
mov ah, 0x00
mov al, 't'
int 0x10
mov ah, 0x00
mov al, 'e'
error:
; Error handling code here
; Pad the boot loader to 512 bytes
times 510 - ($-$$) db 0
dd 0xAA55
I tried removing jmp eax from the assembly code but I feel like that might be a bad move. It did allow everything to get compiled and run in virtualbox but I see no output.
Here's how I built the iso file:
1) dmd -c vmmonitor.d
2) nasm -f elf64 -o bootloader.o boot.asm
3) ld -Ttext 0x7C00 -o boot.bin bootloader.o vmmonitor.o -L /usr/include/dmd/phobos/ -lphobos2
4) genisoimage -o boot.iso -b boot.bin -no-emul-boot boot.bin
dd 0xAA55is the boot signature for a 16-bit legacy BIOS MBR bootloader. The firmware will have the CPU in 16-bit real mode when it jumps to this code at linear address 0x7C00, so you'd better be assembling forbits 16mode, not 64-bit!!int 0x10andint 0x13calls only work in 16-bit mode.jmp eaxshould work, although you you might run into segment limits if it's outside 64K. Also, you wantdwnotddthere;ddwould make a 514 byte file, with two zeros after the boot signature.add edx,ecxand then doubling ECX? Can't you get the same shift-and-add withimul edx, ecx, 0b11111111or something? Maybe that's not the right constant. Also don't forget to setdsbefore using it implicitly via addressing modes like[0x8000 + 0x21A]; BIOSes might leave it set arbitrarily, not necessarily matching CS even. Related: Michael Petch's tips for bootloader development.nasm -fbinto make a flat binary directly;org 0x7c00would tell NASM to assume addresses start at7C00for the first byte of this section, like you're doing withld -Ttext 0x7C00when you assemble into an ELF object file and link. I guess if you want to link with another.oyou could do it this way, but it's often easier to develop the "kernel" separately from the bootloader, not linking into one binary that loads the rest of itself.JMP r/m32is "not supported" in 64-bit mode, the mode you're assembling for withnasm -f elf64which you haven't overridden withbits 16.