Интересный код получил при использовании 20-битной адресации от IAR EW430 5.50.2: uint16_t x, y;
struct z_t {
uint16_t a;
uint64_t b;
};
struct z_t *z;
x += y + z[-3].a;
превратилось в
00BD7C 411F 000A mov.w 0xA(SP),R15
00BD80 1CC0 5B1F FFE2 addx.w 0x9FFE2(R11),R15 ; ***
00BD86 511F 0014 add.w 0x14(SP),R15
00BD8A 4F81 0014 mov.w R15,0x14(SP)
где:
0xA(SP) - y,
0x14(SP) - x,
R11 - z,
0x9FFE2(R11) - z[-3], по мнению IAR-а, а по моему мнению z[-3] должно выглядеть как 0xFFFE2(R11). А именно:
00BD80 1FC0 5B1F FFE2 addx.w 0xFFFE2(R11),R15
биты 7-10 первого слова содержат старшие биты смещения, согласно SLAU208J MSP430x5xx/MSP430x6xx Family User's Guide Figure 6-29.
При z = 0x028FE, &z[-3] вместо 0x028E0, равен 0xA28E0, что за пределами какой-либо памяти и заполнено 0x03FF (jmp $), что собственно и получаю в результате. При установке breakpoint-а на чтение по адресу 0xA28E0 (Advanced Trigger @ 0xA28E0 == [MAB-R]) отладчик останавливается на 2ой инструкции после той, что вызвала сомнения (***) (может pipeline какой или ещё что даёт такой эффект).
Рассудите пожалуйста.
upd.
Если переписать немного, то всё становится на свои места
x += y + (z - 3)->a;
00BD7C 411F 000A mov.w 0xA(SP),R15
00BD80 5B1F FFE2 add.w 0xFFE2(R11),R15 ; ***
00BD84 511F 0014 add.w 0x14(SP),R15
00BD88 4F81 0014 mov.w R15,0x14(SP)
upd2.
Версия 5.51.5 ведёт себя так же.