Всем спасибо за подсказки. Ксения, так слишком муторно получается, да и вероятность ошибиться велика, union больше понравился.
Сделал для пробы такой код:
#include <ioavr.h>
int main( void )
{
union {unsigned char tmp1[4];} tmp;
tmp.tmp1[0]=1;
tmp.tmp1[3]=3;
return 0;
}
IAR сгенерировал следующий код:
+00000000: 940C0036 JMP 0x00000036 Jump
+00000002: 9518 RETI Interrupt return
+00000003: 9518 RETI Interrupt return
+00000004: 9518 RETI Interrupt return
+00000005: 9518 RETI Interrupt return
+00000006: 9518 RETI Interrupt return
+00000007: 9518 RETI Interrupt return
+00000008: 9518 RETI Interrupt return
+00000009: 9518 RETI Interrupt return
+0000000A: 9518 RETI Interrupt return
+0000000B: 9518 RETI Interrupt return
+0000000C: 9518 RETI Interrupt return
+0000000D: 9518 RETI Interrupt return
+0000000E: 9518 RETI Interrupt return
+0000000F: 9518 RETI Interrupt return
+00000010: 9518 RETI Interrupt return
+00000011: 9518 RETI Interrupt return
+00000012: 9518 RETI Interrupt return
+00000013: 9518 RETI Interrupt return
+00000014: 9518 RETI Interrupt return
+00000015: 9518 RETI Interrupt return
+00000016: 9518 RETI Interrupt return
+00000017: 9518 RETI Interrupt return
+00000018: 9518 RETI Interrupt return
+00000019: 9518 RETI Interrupt return
+0000001A: 9518 RETI Interrupt return
+0000001B: 9518 RETI Interrupt return
+0000001C: 9518 RETI Interrupt return
+0000001D: 9518 RETI Interrupt return
+0000001E: 9518 RETI Interrupt return
+0000001F: 9518 RETI Interrupt return
+00000020: 9518 RETI Interrupt return
+00000021: 9518 RETI Interrupt return
+00000022: 9518 RETI Interrupt return
+00000023: 9518 RETI Interrupt return
+00000024: 9518 RETI Interrupt return
+00000025: 9518 RETI Interrupt return
+00000026: 9518 RETI Interrupt return
+00000027: 9518 RETI Interrupt return
+00000028: 9518 RETI Interrupt return
+00000029: 9518 RETI Interrupt return
+0000002A: 9518 RETI Interrupt return
+0000002B: 9518 RETI Interrupt return
+0000002C: E001 LDI R16,0x01 Load immediate
+0000002D: 2F40 MOV R20,R16 Copy register
+0000002E: E003 LDI R16,0x03 Load immediate
+0000002F: 2F70 MOV R23,R16 Copy register
+00000030: E000 LDI R16,0x00 Load immediate
+00000031: E010 LDI R17,0x00 Load immediate
+00000032: 9508 RET Subroutine return
+00000033: 0000 NOP No operation
+00000034: 9588 SLEEP Sleep
+00000035: CFFE RJMP PC-0x0001 Relative jump
+00000036: E90F LDI R16,0x9F Load immediate
+00000037: BF0D OUT 0x3D,R16 Out to I/O location
+00000038: E000 LDI R16,0x00 Load immediate
+00000039: BF0E OUT 0x3E,R16 Out to I/O location
+0000003A: E8C0 LDI R28,0x80 Load immediate
+0000003B: E0D0 LDI R29,0x00 Load immediate
+0000003C: 940E0044 CALL 0x00000044 Call subroutine
+0000003E: 940E002C CALL 0x0000002C Call subroutine
+00000040: 940E0033 CALL 0x00000033 Call subroutine
+00000042: 940C0033 JMP 0x00000033 Jump
+00000044: E001 LDI R16,0x01 Load immediate
+00000045: 9508 RET Subroutine return
Может кто-нибудь пояснить великий смысл функции 0x00000044?
Насчет последовательных call и jmp на 0x00000033 можно списать на специфику построения программ, но все-таки не понятно, почему нужно переходить на nop и нельзя сделать переход сразу на sleep.
Хотя, может этот код вполне нормальный для сишного компилятора, наверное просто сложно отвыкнуть от длительного использования ассемблера.