HNHacker News
TopNewBestAskShowJobs

bd01

23 karma · joined January 2, 2025

submissionscomments
bd01··on The smallest Hello World program
That's because you're using `mov rdi, rax` again. You keep changing `edi, eax` to `rdi, rax`. Why?

The default operand size in 64-bit mode is, for most instructions, still 32 bits. So `mov edi, eax` encodes the same in 32- and 64-bit mode.

For `mov rdi, rax` you need an extra REX prefix byte [1], that's the 48 you're seeing above, but you don't need it here.

[1] https://wiki.osdev.org/X86-64_Instruction_Encoding#REX_prefi...

bd01··on The smallest Hello World program
Yes, because:

  push 1       ; 6A 01 (2 bytes)
  pop rdi      ; 5F    (1 byte)
is longer than a simple:

  mov edi, eax ; 89 C7 (2 bytes)
bd01··on The smallest Hello World program
That second snippet is pretty funny:

  push 1
  pop rax
  pop rdi
You can't push a value once and pop it twice, that's not how a stack works! You're popping something else off the stack. So why does this even work?

Linux passes your program arguments on the stack, with argc on top. So when you don't pass any arguments, argc just HAPPENS to be 1. Which you then pop into rdi. Gross!

bd01··on The smallest Hello World program
Initial register state is documented to be undefined except for rbp, rsp and rdx [1].

Can you say for certain that no other Linux version ever used GPRs to pass something else?

[1] System V ABI, page 29 (last line) and 30, https://refspecs.linuxbase.org/elf/x86_64-abi-0.99.pdf

bd01··on The smallest Hello World program
This is pretty bad. Let's start with the very first instruction:

  mov rax, 1
An actual "mov rax, 1" would assemble to 48 B8 01 00 00 00 00 00 00 00, a whopping TEN bytes.

nasm will optimize this to the equivalent "mov eax, 1", that's 6 bytes, but still:

  xor eax, eax ; 2 bytes
  inc eax      ; 2 bytes
would be much smaller. Second line:

  mov rdi, 1
You already have the value 1 in eax, so a "mov edi, eax" (two bytes) would suffice. Etc. etc.