Search code examples
assemblynested-loopsavrtiming

Determine the running time of a triple nested delay loop


Determine the running time (in nano-seconds) of the following subroutine:

delay:
        push r22
        ldi r20, 0x40
del1:   nop
        ldi r21, 0xFF
del2:   nop
        ldi r22, 0xFF
del3:   nop
        dec r22
        brne del3
        dec r21
        brne del2
        dec r20
        brne del1
        pop r22
        ret

Here's my work:

Inner loop = 1 + 254(1 + 3) + (1 + 2) = 1020
Middle loop = 1 + 254(1020 + 1 + 3) + (1020 + 1 + 2) = 261 120
Outer loop = 1 + 63(261120 + 1 + 3) + (261120 + 1 + 2) = 16 711 936
Total cycles = 16 711 936 + 2 (push) + 1 (ldi) + 2 (pop) + 4 (ret)
             = 16 711 945

Answering just the number of cycles is fine, but if wanted, the microcontroller is an ATMega 2560.


Solution

  • This is the correct answer:

    Inner loop = 1 + 254(1 + 3) + (1 + 2) = 1020
    Middle loop = 1 + 254(1020 + 1 + 3) + (1020 + 1 + 2) = 261 120
    Outer loop = 1 + 63(261120 + 1 + 3) + (261120 + 1 + 2) = 16 711 936
    Total cycles = 16 711 936 + 2 (push) + 1 (ldi) + 2 (pop) + 4 (ret)
                 = 16 711 945
    

    The formula is ldi + (n-1) * (body + ldi + brne_true) + (body + ldi + brne_false)

    • ldi = 1 cycle
    • brne = 2 cycles if true, 1 cycle if false
    • dec = 1 cycle
    • nop = 1 cycle
    • push = 2 cycles
    • pop = 2 cycles
    • ret = 4 cycles

    The body of the inner loop is 1 nop instruction, and we know the cycles for ldi and brne is 3, then 2 for the last iteration.

    The body of the middle loop is 1 nop instruction + the result of the inner loop.

    The body of the outermost loop 1 nop instruction + the result of the middle loop.

    Then the total cycles = the outer loop cycles + push + ldi + pop + ret.

    To get the total time, divide the number of cycles by the clock speed in Hertz.

    Total time = 16711945 / 16000000 = 1.044 seconds or 1044496562.5 nanoseconds