[英]Optimization level breaks the C code order
我有以下 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, [pc, #84]
264: SERCOM0->SPI.DATA.reg = (volatile uint32_t) 0x54;
200001F2 ldr r4, [pc, #88]
265: DMAC->Channel[USB_SEND_SD_DMA_CH].CHCTRLA.reg = (volatile uint8_t) DMAC_CHCTRLA_ENABLE;
200001F4 ldr r0, [pc, #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, [r2, #72]
20000208 strh r2, [r3, #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 规则” ),则编译器 - 在常规情况下 - 允许重新排序指令。 因此,您必须执行以下操作之一:
.reg
变量可变;或通过指针的别名等)具体来说,如果您选择第一个选项,您必须向编译器甚至您自己解释,为什么会这样
第 [264] 行必须在第 265 行之前执行
在什么意义上“必须”在 265 之前执行? 谁会注意到? 这个问题的具体答案很可能是您可以用来强制执行所需顺序的东西。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.