Можно чуть убрать оверхед, используя такой бубен:
Код
#define ONE_NOP(NAME,NEXT_NAME)\
static void delay_##NEXT_NAME(char b);\
static void delay_##NAME(char b) @ "SEG_0100" \
{\
__no_operation();\
delay_##NEXT_NAME(b);\
}\
ONE_NOP(4,3)
ONE_NOP(3,2)
ONE_NOP(2,1)
ONE_NOP(1,0)
#pragma optimize=no_inline
static void delay_0(char b) @ "SEG_0100"
{
PORTB=b;
}
void delay_x(char b, char c)
{
char __flash *p=(char __flash *)(((unsigned int)delay_4&0xFF00)|c);
((void(*)(char))p)(b);
}
При этом создать сегмент SEG_0100 в конфигурации линкера с круглого адреса (кратного 0x100). Результат:
Код
\ In segment CODE, align 2, keep-with-next
22 void delay_x(char b, char c)
\ delay_x:
23 {
24 char __flash *p=(char __flash *)(((unsigned int)delay_4&0xFF00)|c);
25 ((void(*)(char))p)(b);
\ 00000000 .... LDI R31, (delay_4/2) >> 8
\ 00000002 2FE1 MOV R30, R17
\ 00000004 9409 IJMP
26 }
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин