ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Понедельник
22 июля
1205256 Топик полностью
VladislavS. (03.05.2022 01:19, просмотров: 169) ответил VladislavS. на Компилятор как раз таки позаботится о выравнивании и будет ваши 16 бит гонять в 32-битных словах. А если вы ему выкрутите руки и упакуете структуры, то будет побайтово их читать, ибо не умеет контроллер невыровненный доступ. Збсь такая "экономия". Адресация 32-битная, а значит к вашим 16 младшим битам нужно подгрузить и прибавить старшие вместо того чтобы одним чтением загрузить сразу указатель. И нет никакой проблемы с пропускной способностью флэша в современных
Посмотрел таки что получится. Всё с точностью как я и писал. Вместо экономии лишнее чтение адреса начала массива и вычисления адреса элемента массива в рантайме. Скучно. А потом из любопытства упаковал структуру. Вот тут то веселуха и пошла: 

С индексом вместо указателя

void SysTick_Handler()
{   
  static uint16_t i = 0;
  GPIOA->IDR=list.node[i].data.x;
  i = list.node[i].next_i;
}

//void SysTick_Handler()
//{   
//  static uint16_t i = 0;
//  GPIOA->IDR=list.node[i].data.x;
SysTick_Handler:
        LDR      R0,??DataTable1_3   // Чтение из FLASH адреса i         (1)
        LDR      R1,??DataTable1_4   // Чтение из FLASH адреса массива   (2) <-лишнее
        LDRH     R2,[R0, #+0]        // Загрузка i из SRAM               (3)  
        LSLS     R2,R2,#+3           // Вычисление адреса node[i]        (4) <-лишнее
        ADDS     R1,R1,R2            // Вычисление адреса node[i]        (5) <-лишнее
        LDR      R2,[R1, #+0]        // Загрузка data из FLASH           (6)
        LDR      R3,??DataTable1_5   // Чтение из FLASH адреса IDR
        STR      R2,[R3, #+0]        // Запись data в IDR
//  i = list.node[i].next_i;
        LDRH     R1,[R1, #+4]       // Чтение из FLASH нового i          (7)
        STRH     R1,[R0, #+0]       // Запись нового i в SRAM            (8)
//}
        BX       LR

Для сравнения, с указателем

//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

А вот и веселуха

//void SysTick_Handler()
//{   
SysTick_Handler:
        PUSH     {R4,R5,LR}     
//  129   static uint16_t i = 0;
//  130   GPIOA->IDR=list.node[i].data.x;
        LDR      R4,??DataTable1_3
        LDR      R0,??DataTable1_4
        LDRH     R1,[R4, #+0]   
        LSLS     R2,R1,#+1      
        ADDS     R1,R2,R1       
        LSLS     R1,R1,#+1      
        ADDS     R5,R0,R1       
        MOVS     R0,R5          
        BL       __aeabi_uread4     // <- что там не смотрел, но ничего хорошего точно
        LDR      R1,??DataTable1_5
        STR      R0,[R1, #+0]   
//  131   i = list.node[i].next_i;
        LDRH     R0,[R5, #+4]   
        STRH     R0,[R4, #+0]   
//  132 }
        POP      {R4,R5,PC}