0

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.

Peter Cordes
  • 245,674
  • 35
  • 423
  • 606
Shea
  • 128
  • 1
  • 12
  • possible duplicates: https://stackoverflow.com/questions/35750663/calculating-delay-from-3-nested-loops, https://stackoverflow.com/questions/47453737/how-do-avr-assembly-brne-delay-loops-work, https://stackoverflow.com/questions/24097526/how-to-make-a-delay-in-assembly-for-avr-microcontrollers – Peter Cordes Dec 16 '17 at 04:57

2 Answers2

1

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

Shea
  • 128
  • 1
  • 12
0

Just test your assumption in the simulator!

Some hints:

  1. in the outer loop it's not 0xFF that is loaded in the counter variable
  2. 0xFF is not 254, but 255
  3. don't forget to count the return cycles

By the way... you should also push r21 and r20...

yar
  • 1,653
  • 9
  • 24
  • My simulator won't let me do jump to cursor for some reason and running this would take too long. In regards to 1. What is loaded into the counter variable? 2. I know 0xFF is 255, but BRNE is 2 cycles if true and 1 if false, so that's why there's a 254 then a second expression in parentheses being added to it. 3. Yeah that's my bad. Also, please give hints in comments rather than answers. – Shea Dec 15 '17 at 23:11
  • For 1, I see now that it's 0x40 being loaded in the counter variable. – Shea Dec 15 '17 at 23:20