位域使用注意

本文探讨了C语言中的位域操作在编译成汇编代码后的复杂过程,指出其潜在风险,如在读取存储单元后被中断服务函数修改。举例说明了位域设置的具体汇编步骤,并强调了这种操作可能导致的程序异常问题,不推荐在对实时性和安全性要求高的场景下使用位域。
摘要由CSDN通过智能技术生成

 位域使用时虽然语句比较简洁,但是编译成汇编之后,其实比较麻烦,并且存在一定的风险。

例如:

C语言:   PWMx->TBCTL_b.HSPCLKDIV = 0;    // 将PWMx->TBCTL寄存器的7,8,9位写0

汇编 :

0x00000F60 6801      LDR      r1,[r0,#0x00]       ; 将r0地址偏移0个地址之后存储的值赋值给r1寄存器 ,即 r1 =  PWMx->TBCTL

0x00000F3E 2207      MOVS  r2,#0x07            ; 将r2寄存器等于7,即 r2= 0x07   

0x00000F40 01D2      LSLS     r2,r2,#7             ; 将r2寄存器等于r2寄存器左移7位,即 r2 = r2<<7  = 0x0380 

0x00000F42 4391      BICS     r1,r1,r2             ; 将r1寄存器等于r1寄存器第7,8,9位清零, 参考 BIC(位清除)指令

0x00000F44 6001      STR      r1,[r0,#0x00]      ;将r0偏移0个地址中的值放到以r1中的值为地址的存储单元去。

从上面例子可以看出位域操作某个存储单元的某一位或者几位都是通过先把该单元读取出来保存,再把要设置的位清空再赋值,最后把该值再赋值给存储单元;

风险就在如果程序刚把存储单元(数据0x04)读取保存之后,有其他中断响应之后跳转到中断服务函数中也对该存储单元进行修改(将最高位置1),执行完服务函数之后继续执行设置位复制,再把值赋给存储单元(数据0x04),这时在中断中对存储单元写的无效;

不推荐使用位域,不然程序会遇到bug(大部分时候程序是正常跑的,有时会异常),亲身经历这种bug查到怀疑人生。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值