Search code examples
x86nasmbootloaderyasm

Wrong size of compiled bootloader


I am making a bootloader, but it generates a 513 byte output file whereas it should be 512 bits. Here is boot.asm

[ORG 7C00]
[BITS 16]
mov eax,cr0
or eax,1
mov cr0,eax
[BITS 32]
mov ax,10h
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
INT 0x10
jmp 0x8000
TIMES 510 - ($ - $$) DB 0
DW 0xAA55

How can I get 512 byte of output?


Solution

  • You left out the 0x in from of the 7C00 hex constant in your ORG directive . NASM treats this as an error.

    You probably assembled this with YASM, which instead of rejecting your source, produces a 513 byte file. Fixing your source makes both YASM and NASM produce a 512-byte file. This is probably a bug in YASM. Unfortunately YASM hasn't been well maintained recently, so even though it has nicer long NOPs from align directives (not bloating disassembly with many lines of single-byte NOP), you should probably just switch to NASM.

    $ yasm boot-buggy.asm && ll boot-buggy
    -rw-r--r-- 1 peter peter 513 Mar 13 06:03 boot-buggy
    $ nasm boot-buggy.asm && ll boot-buggy
    boot-buggy.asm:1: error: expression syntax error
    boot-buggy.asm:1: error: No or invalid offset specified in ORG directive.
    
    $ nasm boot-fixed.asm && ll boot-fixed
    -rw-r--r-- 1 peter peter 512 Mar 13 06:04 boot-fixed
    $ yasm boot-fixed.asm && ll boot-fixed
    -rw-r--r-- 1 peter peter 512 Mar 13 06:04 boot-fixed
    

    cmp -l boot-fixed boot-buggy shows that the buggy version has an extra 0 byte as the first byte of the file, then all the rest are the same.