目录
1、位域
通过Keil反编译研究了一下 位域的读写操作。
之前一直以为位域的操作就像变量的读写操作一样,同MOV指令一样一条指令搞定,结果不是。
1.1、测试代码:
typedef struct
{
int a : 1;
int b : 1;
int d : 1;
int e : 1;
int f : 1;
} register_t;
register_t reg;
int main()
{
reg.a = 1;
reg.a = 0;
reg.e = 1;
reg.e = 0;
int d = reg.e;
return d;
}
1.2、汇编:
1.3、分析:
reg.e = 1
根据汇编,大致的过程是
拷贝reg的值到R1 | MOV r1 r2 LDR r1,[r1,#100] |
清除R1中的bit4为0 | BIC r1,r1#0x08 |
再设置R1的bit4为1 | ADDS r1,r1,#0x08 |
最后把R1的值又给reg | STR r1,[r2,#0x00] |
一共干了5条指令.......
在圈中部分,如果中途reg的其他位被异常中断修改了,这里就会出现BUG。
当然,只是觉得会出现问题,这个BUG也很难出现。
2、位操作
2.1、测试代码
int main()
{
int reg2;
reg2 |= 0x08;
reg2 &= (~0x08);
}
|= (置位)和 &= (清除)两个操作都是一条指令搞定了。
2.2、位操作汇编对照
reg2 &= ~0x08; | BIC r1,r1,#8 |
reg2 &= 0x08; | AND r1,r1,#8 |
reg2 |= 0x08; | ORR r1,r1,#8 |
reg2 |= ~0x08; | ORN r1,r1,#8 |
结论
就针对keil的ARM汇编指令而言,直接通过位操作符号 |= 和&= 比位域操作效率更高更安全。
版权声明:本文为ai5945fei原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。