Ну это же всё легко проверяется. Берём Cortex-M0+, пишем в
прерывании как у ТС код и смотрим листинги: Компилятор IAR распоследний, оптимизация по скорости. Считать будем только команды работы с массивом. Отправка данных по назначению во всех случаях одинакова. Результаты ожидаемы. И, как ни странно, чтений данных из FLASH (код не считаем) во всех вариантах одинаковое количество. Так как Cortex-M0+ достаточно простая и прямолинейная архитектура, разница в скорости выполнения кода работы с массивом до двух раз видится. Если считать всё прерывание, то ближе к полутора, на глаз.
1. Связный список
void SysTick_Handler()
{
static auto *p=list.node;
GPIOA->IDR=p->data.x;
p=p->next;
}
//void SysTick_Handler()
//{
// static auto *p=list.node;
// GPIOA->IDR=p->data.x;
SysTick_Handler:
LDR R0,??DataTable1_3 // Чтение из FLASH адреса p (1)
LDR R1,[R0, #+0] // Чтение из SRAM p (2)
LDR R2,[R1, #+0] // Чтение из FLASH data (3)
LDR R3,??DataTable1_4 // Чтение из FLASH адреса IDR
STR R2,[R3, #+0] // Запись data в IDR
// p=p->next;
LDR R1,[R1, #+4] // Чтение из FLASH нового p (4)
STR R1,[R0, #+0] // Сохранение p в SRAM (5)
//}
BX LR
2. Инкремент индекса
void SysTick_Handler()
{
static auto i = 0;
GPIOA->IDR=list.node[i].data.x;
if(i<39) i++; else i=0;
}
//void SysTick_Handler()
//{
// static auto i = 0;
// GPIOA->IDR=list.node[i].data.x;
SysTick_Handler:
LDR R0,??DataTable1_3 // Чтение из FLASH адреса i (1)
LDR R1,[R0, #+0] // Чтение из SRAM i (2)
LDR R2,??DataTable1_4 // Чтение из FLASH адреса node[0] (3)
LSLS R3,R1,#+3 // Вычисление адреса node[i] (4)
LDR R2,[R2, R3] // Чтение из FLASH data (5)
LDR R3,??DataTable1_5 // Чтение из FLASH адреса IDR
STR R2,[R3, #+0] // Запись data в IDR
// if(i<39) i++; else i=0;
CMP R1,#+39 // Сравнение на конец массива (6)
BGE ??SysTick_Handler_0 // Условный переход (7)
ADDS R1,R1,#+1 // Инкремент индекса (8)
B ??SysTick_Handler_1 // Накладные условного перехода (9)
??SysTick_Handler_0:
MOVS R1,#+0 // Обнуление индекса (8)
//}
??SysTick_Handler_1:
STR R1,[R0, #+0] // Сохранение i в SRAM (10)либо(9)
BX LR
3. Инкремент указателя
void SysTick_Handler()
{
static auto *p=list.node;
GPIOA->IDR=p->data.x;
if(p<(list.node+39)) p++; else p=list.node;
}
//void SysTick_Handler()
//{
// static auto *p=list.node;
// GPIOA->IDR=p->data.x;
SysTick_Handler:
LDR R0,??DataTable1_3 // Чтение из FLASH адреса p (1)
LDR R1,[R0, #+0] // Чтение из SRAM p (2)
LDR R2,[R1, #+0] // Чтение из FLASH data (3)
LDR R3,??DataTable1_4 // Чтение из FLASH адреса IDR
STR R2,[R3, #+0] // Запись data в IDR
// if(p<(list.node+39)) p++; else p=list.node;
LDR R2,??DataTable1_5 // Чтение из FLASH адреса node[0] (4)
MOVS R3,#+156 // Загрузка константы 39*sizeof(NODE) (5)
LSLS R3,R3,#+1 // Загрузка константы 39*sizeof(NODE) (6)
ADDS R3,R2,R3 // Вычисление адреса node[39] (7)
CMP R1,R3 // Сравнение на конец массива (8)
BCS ??SysTick_Handler_0 // Условный переход (9)
MOVS R2,R1 // Накладные условного перехода (10)
ADDS R2,R2,#+8 // Инкремент указателя (11)
//}
??SysTick_Handler_0:
STR R2,[R0, #+0] // Сохранение p в SRAM (12)либо(10)
BX LR