0

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
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • 1
    `dd 0xAA55` is 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 for `bits 16` mode, not 64-bit!! `int 0x10` and `int 0x13` calls only work in 16-bit mode. `jmp eax` should work, although you you might run into segment limits if it's outside 64K. Also, you want `dw` not `dd` there; `dd` would make a 514 byte file, with two zeros after the boot signature. – Peter Cordes Feb 14 '23 at 02:14
  • 1
    What's up with that sequence of `add edx,ecx` and then doubling ECX? Can't you get the same shift-and-add with `imul edx, ecx, 0b11111111` or something? Maybe that's not the right constant. Also don't forget to set `ds` before 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](https://stackoverflow.com/questions/32701854/boot-loader-doesnt-jump-to-kernel-code). – Peter Cordes Feb 14 '23 at 02:19
  • Also BTW, normally if using NASM, you'd use `nasm -fbin` to make a flat binary directly; `org 0x7c00` would tell NASM to assume addresses start at `7C00` for the first byte of this section, like you're doing with `ld -Ttext 0x7C00` when you assemble into an ELF object file and link. I guess if you want to link with another `.o` you 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. – Peter Cordes Feb 14 '23 at 02:22
  • Anyway, as for the error message in your question, look at the manual: https://www.felixcloutier.com/x86/jmp - the `JMP r/m32` is "not supported" in 64-bit mode, the mode you're assembling for with `nasm -f elf64` which you haven't overridden with `bits 16`. – Peter Cordes Feb 14 '23 at 02:25

0 Answers0