Gccarmnoneeabi 10.3.1做出了我意想不到的行为

我最近在使用gccarm工具链开发stm32,在编译一个freertos程序的时候,由于gccarm做出了一个让我十分意外的行为,让我花了一晚上才找到这个bug

这是出现了bug的函数的源代码:

void SHT2x_Read(void *pvParameters){
    SHT2x_Struct *sht2x = (SHT2x_Struct *)pvParameters;
    static TwoWire SHT20_Wire = TwoWire(sht2x->SDA_Pin, sht2x->SCL_Pin);
    SHT2x sht2x_sensor;
    sht2x_sensor.begin(&SHT20_Wire);

    while(1){
        sht2x_sensor.read();
        float SHT_Temp = sht2x_sensor.getTemperature();  //为了尽可能减小锁申请时间,要省去两次函数调用
        float SHT_Humi = sht2x_sensor.getHumidity();
        
        if(xSemaphoreTake(xMutex, 1000) == pdTRUE){
            //do something
            SHT_msg.SHT_Humi = SHT_Humi;
            SHT_msg.SHT_Temp = SHT_Temp;
            xSemaphoreGive(xMutex);
        }
        vTaskDelay(1000);
    }
}

 可以看到,我在变量SHT20_Wire前加了一个static关键字,如此程序才正常运行,但是按照逻辑来讲,就算我不加这个关键字,程序也应该能正常运行

这是不加static关键字产生的汇编代码

0x08006f54: 30 b5           	push	{r4, r5, lr}
0x08006f56: c3 b0           	sub	sp, #268	; 0x10c
0x08006f58: 42 78           	ldrb	r2, [r0, #1]
0x08006f5a: 01 78           	ldrb	r1, [r0, #0]
0x08006f5c: 09 a8           	add	r0, sp, #36	; 0x24
0x08006f5e: 01 f0 93 fc     	bl	0x8008888 <_ZN7TwoWireC2Emm>
0x08006f62: 68 46           	mov	r0, sp
0x08006f64: 03 f0 ca fc     	bl	0x800a8fc <_ZN5SHT2xC2Ev>
0x08006f68: 09 a9           	add	r1, sp, #36	; 0x24
0x08006f6a: 68 46           	mov	r0, sp
0x08006f6c: 03 f0 a6 fd     	bl	0x800aabc <_ZN5SHT2x5beginEP7TwoWire>
0x08006f70: 0d e0           	b.n	0x8006f8e <_Z10SHT2x_ReadPv+58>
0x08006f72: 11 4b           	ldr	r3, [pc, #68]	; (0x8006fb8 <_Z10SHT2x_ReadPv+100>)
0x08006f74: 5d 60           	str	r5, [r3, #4]
0x08006f76: 1c 60           	str	r4, [r3, #0]
0x08006f78: 00 23           	movs	r3, #0
0x08006f7a: 1a 46           	mov	r2, r3
0x08006f7c: 19 46           	mov	r1, r3
0x08006f7e: 0f 48           	ldr	r0, [pc, #60]	; (0x8006fbc <_Z10SHT2x_ReadPv+104>)
0x08006f80: 00 68           	ldr	r0, [r0, #0]
0x08006f82: fe f7 46 fa     	bl	0x8005412 <xQueueGenericSend>
0x08006f86: 4f f4 7a 70     	mov.w	r0, #1000	; 0x3e8
0x08006f8a: ff f7 a3 f8     	bl	0x80060d4 <vTaskDelay>
0x08006f8e: 68 46           	mov	r0, sp
0x08006f90: 03 f0 28 fe     	bl	0x800abe4 <_ZN5SHT2x4readEv>
0x08006f94: 68 46           	mov	r0, sp
0x08006f96: 03 f0 17 fd     	bl	0x800a9c8 <_ZN5SHT2x14getTemperatureEv>
0x08006f9a: 04 46           	mov	r4, r0
0x08006f9c: 68 46           	mov	r0, sp
0x08006f9e: 03 f0 2f fd     	bl	0x800aa00 <_ZN5SHT2x11getHumidityEv>
0x08006fa2: 05 46           	mov	r5, r0
0x08006fa4: 4f f4 7a 71     	mov.w	r1, #1000	; 0x3e8
0x08006fa8: 04 4b           	ldr	r3, [pc, #16]	; (0x8006fbc <_Z10SHT2x_ReadPv+104>)
0x08006faa: 18 68           	ldr	r0, [r3, #0]
0x08006fac: fe f7 22 fc     	bl	0x80057f4 <xQueueSemaphoreTake>
0x08006fb0: 01 28           	cmp	r0, #1
0x08006fb2: de d0           	beq.n	0x8006f72 <_Z10SHT2x_ReadPv+30>
0x08006fb4: e7 e7           	b.n	0x8006f86 <_Z10SHT2x_ReadPv+50>
0x08006fb6: 00 bf           	nop
0x08006fb8: 80 04           	lsls	r0, r0, #18
0x08006fba: 00 20           	movs	r0, #0
0x08006fbc: 7c 04           	lsls	r4, r7, #17
0x08006fbe: 00 20           	movs	r0, #0

这是加上了static关键字产生的汇编代码:

0x08006f90: 30 b5           	push	{r4, r5, lr}
0x08006f92: 8b b0           	sub	sp, #44	; 0x2c
0x08006f94: 1d 4b           	ldr	r3, [pc, #116]	; (0x800700c <_Z10SHT2x_ReadPv+124>)
0x08006f96: 1b 68           	ldr	r3, [r3, #0]
0x08006f98: 13 f0 01 0f     	tst.w	r3, #1
0x08006f9c: 07 d0           	beq.n	0x8006fae <_Z10SHT2x_ReadPv+30>
0x08006f9e: 01 a8           	add	r0, sp, #4
0x08006fa0: 03 f0 dc fc     	bl	0x800a95c <_ZN5SHT2xC2Ev>
0x08006fa4: 1a 49           	ldr	r1, [pc, #104]	; (0x8007010 <_Z10SHT2x_ReadPv+128>)
0x08006fa6: 01 a8           	add	r0, sp, #4
0x08006fa8: 03 f0 b8 fd     	bl	0x800ab1c <_ZN5SHT2x5beginEP7TwoWire>
0x08006fac: 19 e0           	b.n	0x8006fe2 <_Z10SHT2x_ReadPv+82>
0x08006fae: 42 78           	ldrb	r2, [r0, #1]
0x08006fb0: 01 78           	ldrb	r1, [r0, #0]
0x08006fb2: 17 48           	ldr	r0, [pc, #92]	; (0x8007010 <_Z10SHT2x_ReadPv+128>)
0x08006fb4: 01 f0 98 fc     	bl	0x80088e8 <_ZN7TwoWireC2Emm>
0x08006fb8: 14 4b           	ldr	r3, [pc, #80]	; (0x800700c <_Z10SHT2x_ReadPv+124>)
0x08006fba: 01 22           	movs	r2, #1
0x08006fbc: 1a 60           	str	r2, [r3, #0]
0x08006fbe: 15 48           	ldr	r0, [pc, #84]	; (0x8007014 <_Z10SHT2x_ReadPv+132>)
0x08006fc0: 03 f0 6e fe     	bl	0x800aca0 <atexit>
0x08006fc4: eb e7           	b.n	0x8006f9e <_Z10SHT2x_ReadPv+14>
0x08006fc6: 14 4b           	ldr	r3, [pc, #80]	; (0x8007018 <_Z10SHT2x_ReadPv+136>)
0x08006fc8: 5d 60           	str	r5, [r3, #4]
0x08006fca: 1c 60           	str	r4, [r3, #0]
0x08006fcc: 00 23           	movs	r3, #0
0x08006fce: 1a 46           	mov	r2, r3
0x08006fd0: 19 46           	mov	r1, r3
0x08006fd2: 12 48           	ldr	r0, [pc, #72]	; (0x800701c <_Z10SHT2x_ReadPv+140>)
0x08006fd4: 00 68           	ldr	r0, [r0, #0]
0x08006fd6: fe f7 1c fa     	bl	0x8005412 <xQueueGenericSend>
0x08006fda: 4f f4 7a 70     	mov.w	r0, #1000	; 0x3e8
0x08006fde: ff f7 79 f8     	bl	0x80060d4 <vTaskDelay>
0x08006fe2: 01 a8           	add	r0, sp, #4
0x08006fe4: 03 f0 2e fe     	bl	0x800ac44 <_ZN5SHT2x4readEv>
0x08006fe8: 01 a8           	add	r0, sp, #4
0x08006fea: 03 f0 1d fd     	bl	0x800aa28 <_ZN5SHT2x14getTemperatureEv>
0x08006fee: 04 46           	mov	r4, r0
0x08006ff0: 01 a8           	add	r0, sp, #4
0x08006ff2: 03 f0 35 fd     	bl	0x800aa60 <_ZN5SHT2x11getHumidityEv>
0x08006ff6: 05 46           	mov	r5, r0
0x08006ff8: 4f f4 7a 71     	mov.w	r1, #1000	; 0x3e8
0x08006ffc: 07 4b           	ldr	r3, [pc, #28]	; (0x800701c <_Z10SHT2x_ReadPv+140>)
0x08006ffe: 18 68           	ldr	r0, [r3, #0]
0x08007000: fe f7 f8 fb     	bl	0x80057f4 <xQueueSemaphoreTake>
0x08007004: 01 28           	cmp	r0, #1
0x08007006: de d0           	beq.n	0x8006fc6 <_Z10SHT2x_ReadPv+54>
0x08007008: e7 e7           	b.n	0x8006fda <_Z10SHT2x_ReadPv+74>
0x0800700a: 00 bf           	nop
0x0800700c: 8c 04           	lsls	r4, r1, #18
0x0800700e: 00 20           	movs	r0, #0
0x08007010: 90 04           	lsls	r0, r2, #18
0x08007012: 00 20           	movs	r0, #0
0x08007014: 31 6f           	ldr	r1, [r6, #112]	; 0x70
0x08007016: 00 08           	lsrs	r0, r0, #32
0x08007018: 84 04           	lsls	r4, r0, #18
0x0800701a: 00 20           	movs	r0, #0
0x0800701c: 80 04           	lsls	r0, r0, #18
0x0800701e: 00 20           	movs	r0, #0

我不是很懂汇编,但是这两段汇编代码似乎表明,当我不加上static关键字的时候,SHT20_Wire的地址没有被存入栈中,致使这个地址存放的值在之后的进程中被修改,造成了系统错误

但是我在后面调用了sht2x_sensor.begin函数并将SHT20_Wire的地址传进去,按我的想法来说,编译器应该假设这个类中存在私有变量和这个地址相关联,如此则不应该把这个地址优化掉,而是应该把他保存起来,使之后的函数调用是正常的,但事实却不是这样

我问了问一个比我懂gcc多很多的朋友,他说凡是被取地址的变量,按理来说,不应该被优化,我也相当疑惑为什么gcc会做出这样的优化,是因为我的版本太低吗?还是说这是被写在gcc文档中的优化点吗?

等待回答ing

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值