Search code examples
windowsassemblynasmcalling-convention

Can I use a register as a loop counter?


Since the calling convention of a function states which registers are preserved, can a register be used as a loop counter?

I first thought that the ecx register is used as a loop counter, but after finding out that an stdcall function I have used has not preserved the value of ecx, I thought otherwise.

Is there a register that is guaranteed (by mostly used calling conventions at least) to be preserved?

Note: I don't have a problem in using a stack variable as a loop counter, I just want to make sure that it is the only way.


Solution

  • You can use any general-purpose register, and occasionally others, as the loop counter (just not the stack pointer of course ☺).

    Either you use one to loop manually, i.e. replace…

    loop label
    

    … with…

    dec ebp
    jnz label
    

    … which is faster anyway (because AMD (and later Intel, when they caught up, MHz-wise) artificially slowed down the loop instruction as otherwise, Windows® and some Turbo Pascal compiled software crashed).

    Or you just save the counter in between:

    label:
        push ecx
        call func
        pop ecx
        loop label
    

    Both are standard strategies.