|
Конструкции же делает из инструкций компилятор, и время их выполнения можно точно определить только по сгенерированному КОНКРЕТНЫМ компилятором ассемблерному листингу. Если бы твоя конструкция была написана на ассемблере, то один ее цикл выполнялся бы за 3 такта (при wait типа unsigned char), и выглядела бы так:
.def wait = r16 ; // unsigned char wait;
cycle: dec wait ; 1 такт // while(--wait);
brne cycle ; 2 такта //
Но компилятор так вряд ли сделает - обычно переменные располагаются не в регистрах, а в ОЗУ, и это потребует значительных дополнительных затрат машинного времени, и результирующий код может вырасти многократно. А если wait еще и объявлен int или тем более long, то код (и время цикла соответственно) вырастет до совсем неприличных размеров, например:
.dseg
wait: .byte 4 ; // unsigned long wait;
cycle: lds r16,wait ; 2 такта // while(--wait);
lds r17,wait+1 ; 2 такта //
lds r18,wait+2 ; 2 такта //
lds r19,wait+3 ; 2 такта //
subi r16,1 ; 1 такт //
sbci r17,0 ; 1 такт //
sbci r18,0 ; 1 такт //
sbci r19,0 ; 1 такт //
sts wait,r16 ; 2 такта //
sts wait+1,r17 ; 2 такта //
sts wait+2,r18 ; 2 такта //
sts wait+3,r19 ; 2 такта //
brne cycle ; 2 такта // Итого - 22 такта на цикл,
// притом фактически наверняка еще больше - компилятор "позаботится"
Вывод элементарен - учи ассемблер. И даже не обязательно для того, чтобы на нем писать, а хотя бы для того, чтобы понимать, во что превращает компилятор твои конструкции и что в результате будет делать МК