How to load a kernel from disk with BIOS int 13h in NASM assembly?

assembly, nasm, operating-system, osdev, x86

Solution

`jmp [es:bx]` doesn't jump to the address `es:bx`. This command does a near jump to the address stored in the word at `es:bx`. This is why lots of older assemblers made you spell this kind of instruction as `jmp word ptr [es:bx]` or even `jmp near ptr [es:bx]`; it's clearer this way what is going to happen. What you probably want here is a far jump to a fixed location:

; jmp far 8000:0000
db 0eah
dw 00000h ; offset
dw 08000h ; segment

If you do want to jump to `es:bx`, use `retf`:

push es
push bx
retf

Problem

I've been stuck with this for weeks now and have no idea where I'm going wrong because NASM hasn't given me any errors. The code is pretty self explanatory because of the comments. this is the code that is loaded from the BIOS ``` ;-------------------------------------------- ; 'boot.asm' ; loaded from BIOS [org 0x7C00] [bits 16] ;-------------------------------------------- main: mov ah, 0x0E ; print function mov al, '.' ; ascii char int 0x10 ; IO int resetdisk: mov ah, 0x00 ; reset function mov dl, 0x00 ; drive int 0x13 ; disk int jc resetdisk readdisk: mov bx, 0x8000 ; segment mov es, bx mov bx, 0x0000 ; offset mov ah, 0x02 ; read function mov al, 0x03 ; sectors mov ch, 0x00 ; cylinder mov cl, 0x02 ; sector mov dh, 0x00 ; head mov dl, 0x00 ; drive int 0x13 ; disk int jc readdisk jmp [es:bx] ; buffer ;-------------------------------------------- times 510 - ($ - $$) db 0x00 db 0x55, 0xAA ``` This is the code that should be (but isn't) loaded ``` ;-------------------------------------------- ; 'load.asm' ; loaded from 'boot.asm' [org 0x8000] [bits 16] ;-------------------------------------------- main: mov ah, 0x0E ; print function mov al, '.' ; ascii char int 0x10 ; IO int jmp $ ; hang ``` Any help would be much appreciated. Patrick

Original source