Было:
#define RGA (*(volatile uint16_t*)0xABCD)
#define RGB (*(volatile uint8_t*)0xDCBA)uint8_t foo( uint16_t a) {
RGA = a;
return RGB;
}
Стало:
foo:
sts (-21555)+1,r25
sts -21555,r24
lds r24,-9030
clr r25
ret
Так можно хоть и со структурами - так:
#define STRPTR ((volatile str_t*)0xDEAD)uint8_t moo( uint16_t a, uint8_t b) {
STRPTR->a = a;
STRPTR->b = b;
return STRPTR->b;
}
---------------
moo:
sts (-8531)+1,r25
sts -8531,r24
sts -8529,r22
lds r24,-8529
clr r25
ret
или так
#define STRU (*(volatile str_t*)0xDEAD)
uint8_t kwa( uint16_t a, uint8_t b) {
STRU.a = a;
STRU.b = b;
return STRU.b;
}
----------------------
kwa:
sts (-8531)+1,r25
sts -8531,r24
sts -8529,r22
lds r24,-8529
clr r25
ret
По вкусу - реально разницы нет, как больше нравится записывать.
В свете вышеизложенного, которое работало на "Электронике-60"/"ДВК" и никуда не делоьс сейчас - меня всегда удивляла страсть к непереносимым с компилятора на компилятор расширениям, "привязывающим" данные к фиксированным адресам.
Кстати, volatile обязательно, так как иначе ни 0xAAAA/0x5555 подряд не запишешь (компилятор уоптимизирует две записи в одну переменную), ни данные не прочтёшь для проверки после того, как записал - компилятор может "уоптимизировать" до возврата того, что сам туда писал.