位域结构体变量在主流控制器(ARM/DSP等)编程使用时注意事项

        出处:http://blog.csdn.net/peasant_lee/article/details/5592190

        很多人搞电子软件编程的人都是从sram很紧缺的51单片机或其他低端单片机入门的。大家都知道,51单片机的有个可bit寻址的空间,而对应的开发环境KEIL C51当然也支持bit变量。随着电子芯片产品的发展,现在的主控器林林种种,无论是SRAM空间或者是COED空间,都有了相当大的提升,现在的sram动不动就几k,几十k。而51单片机的可位寻址功能没有得到继承,已经永久的成为古董。而在实际编程应用中,有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位。比如很多的变量,特别是标志位,都不需要占用一个byte的空间。常见的如:只占用一bit的的bool变量(0或1)。那么,假如不是51单片机编译环境,而又为了省SRAM存储空间,需要这种不足一个byte空间的变量,又怎么办呢?位域结构体派上用场了。位域结构体,称为“位域”或“位段”。所谓“位域”是把一个字节中的二进位划分为几个不同的区域,并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。 这样就可以把几个不同的对象用一个字节的二进制位域来表示。

位域结构体的声明如下:

 

struct 位域结构名

  {类型说明符 位域名:位域长度};

 

例如:

struct bitzone
{
 int a:8;
 int b:2;
 int c:6;
};

 

当然了,还有其他位域名和位域长度缺省的情况,具体代表什么意思,大家可参考其他资料,很多有说明的。

位域结构体变量的定义和调用同一般的结构体变量一样,估计大家都很熟悉,在这里不再多说了,而我想说的是,位域结构体无疑是可以为我们节省一些变量存储空间。但是,正因为现在很多主控器,比如DSP,ARM,和其他的高端单片机,都没有了可位寻址的区域,它们要实现这种类似位操作的数据结构,就需要将当前bit所在的byte进行位&,或者移位等操作。而这,撇开代码是否美观不管,就生成代码量多了,需要占用的CPU周期多了。换句话说,为了节省这个SRAM,代价是代码臃肿了,机器跑起来慢了。本人曾经在DSP和ARM的开发环境,测试过,的确如此。如何进行取舍呢?那就看具体的情况了,假如SRAM 紧张,CODE不紧张,慢几个机器周期也无所谓,那行,就用上它。假如都紧张,而且CPU很忙,不能再忙了,那么就只能来个折中取舍了,正所谓,鱼与熊掌不可兼得啊。

 

///

 

下面再给出一个我自己很久前写的代码例子,以示为呈堂证供:

 

///

 

情况1:下面的结构体内定义了位域结构体

typedef struct _DECODE_PARAMETER

{

       UINT16  selectindex;  

       UINT16  decodeindex;

       …………

       …………

       struct _BIT    

       {

              UINT16 fileover:                 1;

              UINT16 validname:             1;

              UINT16 playstatus:              2;

              …………….

              …………….

              …………….

       }bit;

 

} DECODE_PARAMETER;

 

///

 

情况2:下面结构体中没有位域变量

typedef struct _DECODE_PARAMETER

{

      

       UINT16  selectindex;  

       UINT16  decodeindex;

//上面的位域去掉,每项位域直接定义位char变量:

       UINT8 fileoverflag ;

       UINT8 validname;

       UINT8 playstatus; 

       …………………..

…………………..

 

} DECODE_PARAMETER;

 

///

 

使用实例比较:在使用过程中,做同样的与判断。

 

///

 

情况1:if(Side.bit.fileover && Side.bit.validname && Side.bit.playstatus)

生成的汇编代码为:

0x08004632 48E4      LDR      r0,[pc,#912]  ; @0x080049C4 

0x08004634 F8B00044  LDRH     r0,[r0,#0x44]

0x08004638 F3C00000  UBFX     r0,r0,#0,#1

0x0800463C B310      CBZ      r0,0x08004684

0x0800463E 48E1      LDR      r0,[pc,#900]  ; @0x080049C4

0x08004640 F8B00044  LDRH     r0,[r0,#0x44]

0x08004644 F3C01000  UBFX     r0,r0,#4,#1

0x08004648 B1E0      CBZ      r0,0x08004684

0x0800464A 48DE      LDR      r0,[pc,#888]  ; @0x080049C4

0x0800464C F8B00044  LDRH     r0,[r0,#0x44]

0x08004650 F3C01041  UBFX     r0,r0,#5,#2

0x08004654 B1B0      CBZ      r0,0x08004684

 

///

 

情况2:if(Side.fileover && Side.validname && Side.playstatus)

生成的汇编代码为:

0x0800421C 48C5      LDR      r0,[pc,#788]  ; @0x08004534

0x0800421E F8900044  LDRB     r0,[r0,#0x44]

0x08004222 B1B8      CBZ      r0,0x08004254

0x08004224 48C3      LDR      r0,[pc,#780]  ; @0x08004534

0x08004226 F8900048  LDRB     r0,[r0,#0x48]

0x0800422A B198      CBZ      r0,0x08004254

0x0800422C 48C1      LDR      r0,[pc,#772]  ; @0x08004534

0x0800422E F8900049  LDRB     r0,[r0,#0x49]

0x08004232 B178      CBZ      r0,0x08004254

 

看出区别了吧?明显的情况2少了3个指令。明显是多了Crotex m3特有的UBFX(位段提取)指令。具体其他的汇编代码指令具体做什么操作,大家有兴趣的话,查相关资料。大家可能觉得在上百M或者几百M的CPU中,三个指令周期算不了什么,那就错了,假如该判断在循环相当频繁的主循环中(每个主循环的必经之路),一个指令包含了若干个机器周期,那么,这些若干的周期,就真的以少积多,滴水成河了。我也亲自试验过,在MP3的解码播放中,两种用法的区别。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言中的共用(Union)和位(Bit-Field)是用来优化内存使用和灵活操作数据的工具。 共用是一种特殊的数据类型,它允许不同的变量共享同一块内存空间。共用中的成员变量共享同一内存,占用内存大小等于最大成员的大小。通过修改共用的一个成员变量的值,可以影响到其他成员变量的值。共用适用于在不同的数据类型之间进行转换或者存储占用内存大小不定的数据。 位是一种特殊的结构成员变量,可以指定成员变量占用的位数,从而实现对内存空间的灵活利用。位的成员变量必须是整型数据类型,并且位的大小不能超过该整型类型的大小。位可以用于减小数据结构占用的内存大小,以及进行数据的位操作。 共用和位结构可以一起使用。通过在位结构中定义共用成员变量,可以实现对内存的灵活使用和数据的高效操作。共用可以用于存储不同类型的数据,而位可以用于压缩数据的存储空间。这种结合使用的方式可以为我们的程序带来更加高效和节省内存的特点。 总结起来,C语言中的共用和位结构提供了一种优化内存使用和操作数据的方式。它们可以灵活地对内存空间进行利用,并且能够高效地操作数据。通过合理的使用共用和位结构,我们可以达到节省内存和提高程序执行效率的目的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值