According to the x86 ABI, EBX
, ESI
, EDI
, and EBP
are callee-save registers and EAX
, ECX
and EDX
are caller-save registers.
It means that functions can freely use and destroy previous values EAX
, ECX
, and EDX
.
For that reason, save values of EAX
, ECX
, EDX
before calling functions if you don’t want their values to change. It is what “caller-save” mean.
Or better, use other registers for values that you’re still going to need after a function call. push/pop of EBX
at the start/end of a function is much better than push/pop of EDX
inside a loop that makes a function call. When possible, use call-clobbered registers for temporaries that aren’t needed after the call. Values that are already in memory, so they don’t need to written before being re-read, are also cheaper to spill.
Since EBX
, ESI
, EDI
, and EBP
are callee-save registers, functions have to restore the values to the original for any of those they modify, before returning.
ESP
is also callee-saved, but you can’t mess this up unless you copy the return address somewhere.