Question

Consider the following code:

ArraySum PROC 
; Receives: ESI points to an array of doublewords, 
; ECX = number of array elements. 
; Returns: EAX = sum 
;----------------------------------------------------- 
    push esi ; save ESI, ECX 
    push ecx 
    mov eax,0 ; set the sum to zero 

L1:
    add eax,[esi] ; add each integer to sum 
    add esi,4 ; point to next integer 
    loop L1 ; repeat for array size 
    pop ecx ; restore ECX, ESI 
    pop esi 
    ret 
ArraySum ENDP 

Why did the coder decided to save the values of ESI and ECX? I mean, the one which calls ArraySum from somewhere must 'prepare' both ESI and ECX for ArraySum.

Less specific, what registers should I save when writing a function? Just the ones I use without anyone from outside the function knowing it, or all of the registers I use except the ones which are used to return values?

Était-ce utile?

La solution

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top