1

I was wondering how NASM works with this piece of code:

Just let you know that it is loaded at 0x1000 by a bootloader, and the bootloader goes into protected mode (setup GDT with segments covering whole memory, setup segment registers...) before jumping to 0x1000 (this piece of code):

[bits 32]
[org 0x0]

jmp test

loop:
jmp loop

test:
mov byte [0xB8000], 'H'
mov byte [0xB8001], 0x57

end:
jmp end

When I compile this code in a separate file, how NASM knows the address of test label in memory to jump (it should be 0x1000 + difference in file)? Because it works but I don't understand how.

1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56
Leosa99 _
  • 33
  • 6
  • 2
    Your `org` directive is lying to the assembler: you're telling it that the code will be loaded starting at offset `0x0`, whereas you are actually loading it at offset `0x1000`. But it won't matter here because `jmp test` is a relative jump: it only needs to know the *difference* in addresses between the end of the `jmp` instruction and the label `test`, which in this case is 2 bytes (the length of the `jmp loop` instruction that is in between). – Nate Eldredge Aug 15 '21 at 01:07
  • 1
    `jmp` to a label uses *relative* jumps (`jmp rel8` or `jmp rel32` https://www.felixcloutier.com/x86/jmp), so the code is position-independent. – Peter Cordes Aug 15 '21 at 01:08
  • 3
    So the assembler *does* think that label `test` is at offset `0x0004`. But that information doesn't happen to play into the generated code in this case. If you use `test` as an absolute address somewhere (`mov eax, test / jmp eax`) it will fail. – Nate Eldredge Aug 15 '21 at 01:08

0 Answers0