Search code examples
assemblyavr

Determining how many clock cycles AVR assembly language code will take to execute


If I was given Assembly code like the below, how could I determine how many clock cycles it will take to execute?

      ldi r20, 250
loop: inc r20
      brne loop
      nop

In the datasheet, all the instructions take up 16 bits (1 instruction word).

Attempting it myself, I get 14 as the answer. Since ldi r20, 250 is called once (1 cycle), then the loop is called 6 times before overflow to zero occurs (6x2=12 cycles). And finally at the end, nop takes 1 cycle. In total that is 14 cycles.

However, the answer is apparently 19 cycles. Would anyone be able to tell me what I have done wrong?


Solution

  • You've skipped including the inc at each loop. So each loop will be brne (2) + inc (1). Therefore your calculation should be (r20 value in brackets):

    1
    1 (251)
    2
    1 (252)
    2
    1 (253)
    2
    1 (254)
    2
    1 (255)
    2
    1 (0)
    1
    1
    

    The brne is 1 cycle when the branch is not taken.

    Its a bit more visible if you unroll that loop:

    ; (4 cycles)
    ldi r20, 250 ; 1
    inc r20      ; 1
    nop          ; these two represent the brne at 2 cycles because it branches
    nop
    
    ; (3 cycles)
    inc r20      ; 1
    nop          ; these two represent the brne at 2 cycles because it branches
    nop
    
    ; (3 cycles)
    inc r20      ; 1
    nop          ; these two represent the brne at 2 cycles because it branches
    nop
    
    ; (3 cycles)
    inc r20      ; 1
    nop          ; these two represent the brne at 2 cycles because it branches
    nop
    
    ; (3 cycles)
    inc r20      ; 1
    nop          ; these two represent the brne at 2 cycles because it branches
    nop
    
    ; (2 cycles)
    inc r20      ; 1
    nop          ; this represents the brne at 1 cycle, because its just overflowed and therefore ** will not branch **
    
    ; (1 cycle)
    nop