例:
_DEVICE_RCC.CR &= ~(BIT(1));  // 清除CR的第(1+1)位,相当於 _DEVICE_RCC.CR &= 0xFFFF FFFD
(以下内容的编译为IAR5.20)
 \ 00000000 0748     LDR.N  R0,??main_0  ;; 0x40021000
 \ 00000002 0168     LDR  R1,[R0, #+0]
 \ 00000004 0222     MOVS R2,#+2    ;//主要是这一条和下一条语句, MOV(S),赋值
 \ 00000006 9143     BICS R1,R1,R2    ;//BIC(S),位清除
 \ 00000008 0160     STR  R1,[R0, #+0]
上面中间两条的汇编的意思很明显,让 R2 = 2 , 再清除 R1 的第2位.
但如果,把原程序稍改一下,
_DEVICE_RCC.CR &= ~(BIT(8));  // 清除CR的第(8+1)位,
(以下内容的编译为IAR5.20)
 \ 00000000 0748     LDR.N  R0,??main_0  ;; 0x40021000
 \ 00000002 0168     LDR  R1,[R0, #+0]
 \ 00000004 6FF48072   MVN  R2,#+256  ;//主要是这一条和下一条语句, MVN 取补码
 \ 00000008 1140     ANDS R1,R2,R1 ;//AND(S) 位“与”
 \ 0000000A 0160     STR  R1,[R0, #+0]
它就变成了上面的形式了。
上面中间两条的汇编的意思是:
R2= 0x00000100 (256) ,再 R2 = ~R2 = FFFFFEFF,然后再与R1相与R1 = R1 & R2
虽然,最终的结果是一样的,目的也是一样的,但不同的位置,IAR却做出了不同的汇编语句,怪不?
小结:第1~8位 ( BIT(0) ~ BIT(7) ) , IAR 使用第一种的方式,也就是位清除的方式。
第9~32位 ( BIT(8) ~ BIT(31), IAR 使用的是第二种的方式,也就是取反,再与。
==================================================================
以上的IAR 5.20的编译环境下的汇编,但在IAR5.30,则变了。
 15    _DEVICE_RCC.CR &= ~BIT(1);
 \ 00000008 0168     LDR  R1,[R0, #+0]
 \ 0000000A 21F00201   BIC  R1,R1,#0x2
 \ 0000000E 0160     STR  R1,[R0, #+0]
 19    _DEVICE_RCC.CR &= ~BIT(8);
 \ 00000014 0168     LDR  R1,[R0, #+0]
 \ 00000016 21F48071   BIC  R1,R1,#0x100
 \ 0000001A 0160     STR  R1,[R0, #+0]
 20    
 21    _DEVICE_RCC.CR &= ~BIT(18);
 \ 0000001C 0168     LDR  R1,[R0, #+0]
 \ 0000001E 21F48021   BIC  R1,R1,#0x40000
 \ 00000022 0160     STR  R1,[R0, #+0]
不管是哪个位,都是使用位清除的指令,比以前的优化了很多。