Evening all,
I've spent the last few evenings trying to figure out how to precisely time sections of my code with assembly NOP instructions. I'm struggling because I'm not getting the results I'm expecting. I'm using an Uno board...
Initially I was adding some NOP instructions to my code to see how the assembly is affected and was suprised that the NOP's were not appering in the listing as I expected. A single instruction appears but multiple instructions just put a "..." in the listing... Can anyone explain this?
I am already aware of the 4us resolution limit of the micros() funcion but I'm still confused at the results I'm getting.
This code prints "took 20us":
unsigned long start = micros();
delayMicroseconds(16);
unsigned long finished = micros();
Serial.print("took ");
Serial.print(finished - start);
Serial.println("us");
But this code prints "took 4us":
unsigned long start = micros();
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
unsigned long finished = micros();
Serial.print("took ");
Serial.print(finished - start);
Serial.println("us");
Can anyone explain why? Are the NOP instructions being optimised out by the compiler? I didn't think that should happen...
If anyone can point me to a good resource for learning about the listing files generated by avr-objdump or for learning how I can understand and control the timing of my code that would be amazing.
Pulling my hair out!
Cheers, Tom