优化级别破坏了C代码顺序

问题描述

我有以下5行代码,并希望这些行以O2或O3的确切顺序执行:

    PORT->Group[GPIO_PORTB].OUTCLR.reg = (volatile uint32_t) 1 << 9;
    TC3->COUNT16.COUNT.reg =  (volatile uint16_t) 0;
    TC3->COUNT16.CC[0].reg = (volatile uint16_t) vusb_driver->in_data->bitlength;
    SERCOM0->SPI.DATA.reg = (volatile uint32_t) 0x54;
    DMAC->Channel[USB_SEND_SD_DMA_CH].CHCTRLA.reg = (volatile uint8_t) DMAC_CHCTRLA_ENABLE;

如果我使用O2或O3进行优化,则代码将在264行中断,因为该行必须在265行之前执行:

  261:      PORT->Group[GPIO_PORTB].OUTCLR.reg = (volatile uint32_t) 1 << 9;
200001EE   ldr  r1,[pc,#84]        
   263:         TC3->COUNT16.CC[0].reg = (volatile uint16_t) vusb_driver->in_data->bitlength;
200001F0   ldr  r5,#84]        
   264:         SERCOM0->SPI.DATA.reg = (volatile uint32_t) 0x54;
200001F2   ldr  r4,#88]        
   265:         DMAC->Channel[USB_SEND_SD_DMA_CH].CHCTRLA.reg = (volatile uint8_t) DMAC_CHCTRLA_ENABLE;
200001F4   ldr  r0,#88]        
   261:         PORT->Group[GPIO_PORTB].OUTCLR.reg = (volatile uint32_t) 1 << 9;
200001F6   mov.w    r6,#512         
200001FA   str.w    r6,[r1,#148]       
   262:         TC3->COUNT16.COUNT.reg =  (volatile uint16_t) 0;
200001FE   strh r2,[r3,#20]        
   263:         TC3->COUNT16.CC[0].reg = (volatile uint16_t) vusb_driver->in_data->bitlength;
20000200   ldr  r2,[r5]         
20000202   ldr  r2,[r2,#20]        
20000204   ldrh.w   r2,#72]        
20000208   strh r2,#28]        
   264:         SERCOM0->SPI.DATA.reg = (volatile uint32_t) 0x54;
2000020A   movs r5,#84      
   265:         DMAC->Channel[USB_SEND_SD_DMA_CH].CHCTRLA.reg = (volatile uint8_t) DMAC_CHCTRLA_ENABLE;
2000020C   movs r2,#2       
   264:         SERCOM0->SPI.DATA.reg = (volatile uint32_t) 0x54;
2000020E   str  r5,[r4,#40]   

 

解决方法

您对volatile的使用是不正确的,您应将目标对象定义为volatile,以确保按照程序顺序正确写入目标对象。

,

在正常情况下,如果执行的效果相同(这是"as-if rule"),则允许编译器对指令重新排序。因此,您必须执行以下操作之一:

  • 表明指令有不同的作用(例如,使相关的.reg变量易变;或通过指针的别名等)
  • 使用某种特定于编译器的指令来控制其行为。
  • 不进行编译,即以不同的方式生成您的机器代码。

具体来说,如果您选择第一个选项,则必须向编译器或您自己解释为什么?

第[264]行必须在第265行之前执行

在什么意义上“必须”在265之前执行?谁会注意到?您可以使用该问题的具体答案来强制执行所需的执行顺序。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...