Why is the value of EDX overwritten when making call to printf?

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.

Leave a Comment