Why does a function start with push %rbx + mov %rdi, %rbx? What does this two-instruction pattern mean?
It stashes the first argument (%rdi) into a callee-saved register (%rbx) so the value survives the upcoming calls that would otherwise clobber %rdi.
* The arg in caller-saved %rdi is stashed into callee-saved %rbx so it survives a later call that clobbers %rdi. *
phase_1:
push %rbx
mov %rdi, %rbx
call <phase_init>
mov $0x402490, %esi
mov %rbx, %rdi
call <strings_not_equal>
Step by step:
push %rbx— saves the old%rbx(callee-saved, we must preserve it)mov %rdi, %rbx— copies our input string pointer to%rbxcall <phase_init>— this call may trash%rdi(it's caller-saved!) but%rbxis safemov %rbx, %rdi— restore the argument from%rbxback into%rdifor the next call
The key insight: %rdi is caller-saved — any call can destroy it. If the function needs the argument again later, it must stash it somewhere safe. A callee-saved register (%rbx, %rbp, %r12-%r15) is guaranteed to survive across calls.
General rule: If you see push %r12 + mov %rdi, %r12 at function entry, it means "I need the first argument to survive across function calls."
Go deeper: