Search code examples
assemblyx86stackbootloaderreal-mode

Bootloader stack set up


I am currently trying to understand a certain piece of code. I found here:
http://mikeos.sourceforge.net/write-your-own-os.html

Specifically the first 2 lines under the start label:

    BITS 16

start:
    mov ax, 07C0h       ; Set up 4K stack space after this bootloader
    add ax, 288     ; (4096 + 512) / 16 bytes per paragraph
    mov ss, ax
    mov sp, 4096

    mov ax, 07C0h       ; Set data segment to where we're loaded
    mov ds, ax


    mov si, text_string ; Put string position into SI
    call print_string   ; Call our string-printing routine

    jmp $           ; Jump here - infinite loop!


    text_string db 'This is my cool new OS!', 0


print_string:           ; Routine: output string in SI to screen
    mov ah, 0Eh     ; int 10h 'print char' function

.repeat:
    lodsb           ; Get character from string
    cmp al, 0
    je .done        ; If char is zero, end of string
    int 10h         ; Otherwise, print it
    jmp .repeat

.done:
    ret


    times 510-($-$$) db 0   ; Pad remainder of boot sector with 0s
    dw 0xAA55       ; The standard PC boot signature

The tutorial says "those lines aren't really of interest for us", but I'd really like to know. So what is "07C0h"? At first I thought it would be the address to which the BIOS loads the bootloader, but from what I read the address is "7C00h". And what is this "(4096 + 512) / 16 bytes per paragraph" supposed to mean? I'd also like to know what "$$" is (I know what "$" is).


Solution

  • Yes, that's the address, expressed as the segment. In real mode physical address = 16 * segment + offset so the physical address 7c00h can be written as 7c0h:0 (that's not the only way). Each paragraph is 16 bytes and changing the segment by 1 changes the physical address by that amount.

    To get 4096 bytes of stack the load address is incremented by said 4096 bytes plus the size of the boot sector which is 512 bytes then the whole thing is divided by 16 to get the segment value.

    $$ is a special symbol denoting the start of the current section. See the nasm manual.

    PS: there is really no need to do it at runtime, the code could simply use mov ax, 07C0h + 288 or similar.