Если писать на ассемблере самому, или на Си с выключеной
оптимизацией, - то волятильность ничего не даёт. Иначе компилятор
наоптимизирует так, что программа может перестать работать.
Например, объявлены две переменные, им присвоены значения, после
эти переменные проверяются, по результатам модифицируются порты.
Текст на Си: volatile char vol_c;
char no_vol_c;
__C_task void main(void)
{
vol_c = 5;
no_vol_c = 5;
if (vol_c) PORTB = 1;
if (no_vol_c) PORTC = 2;
Теперь смотрим листинг с вЫключеной оптимизацией, он самый полный:
638 vol_c = 5;
\ 00000000 E005 LDI R16, 5
\ 00000002 9300.... STS vol_c, R16
639 no_vol_c = 5;
\ 00000006 E005 LDI R16, 5
\ 00000008 9300.... STS no_vol_c, R16
641 if (vol_c) PORTB = 1;
\ 0000000C 9100.... LDS R16, vol_c
\ 00000010 2300 TST R16
\ 00000012 F011 BREQ ??main_0
\ 00000014 E001 LDI R16, 1
\ 00000016 BB08 OUT 0x18, R16
642 if (no_vol_c) PORTC = 2;
\ ??main_0:
\ 00000018 9100.... LDS R16, no_vol_c
\ 0000001C 2300 TST R16
\ 0000001E F011 BREQ ??main_1
\ 00000020 E002 LDI R16, 2
\ 00000022 BB05 OUT 0x15, R16
Обе переменные проверяются. Теперь листинг с включённой оптимизацией:
638 vol_c = 5;
\ 00000000 E005 LDI R16, 5
\ 00000002 9300.... STS vol_c, R16
639 no_vol_c = 5;
\ 00000006 9300.... STS no_vol_c, R16
641 if (vol_c) PORTB = 1;
\ 0000000A 9100.... LDS R16, vol_c
\ 0000000E 2300 TST R16
\ 00000010 F011 BREQ ??main_0
\ 00000012 E001 LDI R16, 1
\ 00000014 BB08 OUT 0x18, R16
642 if (no_vol_c) PORTC = 2;
\ ??main_0:
\ 00000016 E002 LDI R16, 2
\ 00000018 BB05 OUT 0x15, R16
Выделенное зелёным маркером компилятор взял и выкинул. Почему? :))