I wrote a simple Hello world program in NASM, to then look at using objdump -d
out of curiosity. The program is as follows:
BITS 64
SECTION .text
GLOBAL _start
_start:
mov rax, 0x01
mov rdi, 0x00
mov rsi, hello_world
mov rdx, hello_world_len
syscall
mov rax, 0x3C
syscall
SECTION .data
hello_world: db "Hello, world!", 0x0A
hello_world_len: equ $-hello_world
When I inspected this program, I found that the actual implementation of this uses movabs
with the hex value 0x402000
in place of a name, which makes sense, except for the fact that surely this would mean that it knows 'Hello, world!' is going to be stored at 0x402000
everytime the program is run, and there is no reference to 'Hello, world!' anywhere in the output of objdump -d hello_world
(the output of which I provided below).
I tried rewriting the program; This time I replaced hello_world
on line 8 with mov rsi, 0x402000
and the program still compiled and worked perfectly.
I thought maybe it was some encoding of the name, however changing the text 'hello_world' in SECTION .data
did not change the outcome either.
I'm more confused than anything - How does it know the address at compile time, and how come it never changes, even on recompilation?
(OUTPUT OF objdump -d hello_world
)
./hello_world: file format elf64-x86-64
Disassembly of section .text:
0000000000401000 <_start>:
401000: b8 01 00 00 00 mov $0x1,