section .data

bits 32

global multiboot_reloc_stub
multiboot_reloc_stub:
    jmp .code

    times 4-($-multiboot_reloc_stub) db 0

    ; EBX = self
    ; ESI = magic value
    ; EDI = protocol info
    ; ECX = entry point
    ; EAX = ranges
    ; EDX = ranges count

  .code:
    mov esp, ebx
    add esp, .mini_stack_top - multiboot_reloc_stub

    push edi
    push esi
    push ecx

  .ranges_loop:
    test edx, edx     ; Loop until we're done
    jz .ranges_loop_out

    mov esi, [eax]    ; ESI = range.elsewhere
    mov edi, [eax+8]  ; EDI = range.target
    mov ecx, [eax+16] ; ECX = range.length
    rep movsb         ; Copy range to target location

    add eax, 24       ; Move to the next range

    dec edx
    jmp .ranges_loop

  .ranges_loop_out:
    ; We're done relocating!
    pop ecx
    pop esi
    pop edi

    push ecx

    mov eax, esi ; EAX = magic value
    mov ebx, edi ; EBX = protocol info
    xor ecx, ecx
    xor edx, edx
    xor esi, esi
    xor edi, edi
    xor ebp, ebp

    ret

    align 16
 .mini_stack:
    times 3 dq 0
 .mini_stack_top:

global multiboot_reloc_stub_end
multiboot_reloc_stub_end:

section .note.GNU-stack noalloc noexec nowrite progbits
