In 32-bit x86 code, the callee-saved registers (i.e. the ones functions should preserve) are EDI
, ESI
, EBP
, and EBX
. The function you've shown modifies ESI
inside the loop and therefore needs to save its original value and restore it before returning.
ECX
is among the caller-saved registers (i.e. it's up the the callers of the function to preserve its value if it needs it), so it's unclear why the function you've shown saves it. Perhaps the coder made up his/her own calling convention.
See table 4 in Agner Fog's "Calling conventions" document.