如何使用 SDCC 创建位字段的打包数组?
How to create packed arrays of bit fields with SDCC?
我有一个包含位字段数组的嵌套数据结构,我需要使用 SDCC 为 MCS-51 目标编译它。
这是一个简化的例子:
example.c
struct data {
unsigned char a : 1;
unsigned char b : 2;
};
struct data dummy[8];
void main()
{
}
由于struct data
包含3位,8个实例一共包含24位,所以3个字节的内存就足够了。
但是 SDCC 分配了 8 个字节,正如我们在结果中看到的 example.asm
:
$ sdcc -c example.c
$ cat example.asm
[…]
; File Created by SDCC : free open source ANSI-C Compiler
; Version 3.5.0 #9253 (Mar 19 2016) (Linux)
[…]
.module example
.optsdcc -mmcs51 --model-small
[…]
.area DSEG (DATA)
_dummy::
.ds 8
有没有办法让 SDCC 只为 dummy
分配 3 个字节?
作为一种解决方法,我目前根本没有使用 struct
,而是使用一些宏来计算数据结构的总大小、分配平面字节数组以及生成索引和位用于访问各个成员的掩码。我想改用 dummy[5].b
这样的语法。
一些编译器似乎有启用位字段打包的选项(如 #pragma pack
),但我在 SDCC 手册中没有找到类似的内容。
恐怕在任何编译器中都不可能。它会为每个结构分配至少一个字节
我会这样做:
typedef struct {
unsigned char a0 : 1;
unsigned char b0 : 2;
unsigned char a1 : 1;
unsigned char b1 : 2;
unsigned char a2 : 1;
unsigned char b2 : 2;
unsigned char a3 : 1;
unsigned char b3 : 2;
unsigned char a4 : 1;
unsigned char b4 : 2;
unsigned char a5 : 1;
unsigned char b5 : 2;
unsigned char a6 : 1;
unsigned char b6 : 2;
unsigned char a7 : 1;
unsigned char b7 : 2;
}data;
data dx;
#define GT(dt,member,bit) ((dt).member ##bit)
void foo()
{
GT(dx,b,5) = 2;
}
我有一个包含位字段数组的嵌套数据结构,我需要使用 SDCC 为 MCS-51 目标编译它。
这是一个简化的例子:
example.c
struct data {
unsigned char a : 1;
unsigned char b : 2;
};
struct data dummy[8];
void main()
{
}
由于struct data
包含3位,8个实例一共包含24位,所以3个字节的内存就足够了。
但是 SDCC 分配了 8 个字节,正如我们在结果中看到的 example.asm
:
$ sdcc -c example.c
$ cat example.asm
[…]
; File Created by SDCC : free open source ANSI-C Compiler
; Version 3.5.0 #9253 (Mar 19 2016) (Linux)
[…]
.module example
.optsdcc -mmcs51 --model-small
[…]
.area DSEG (DATA)
_dummy::
.ds 8
有没有办法让 SDCC 只为 dummy
分配 3 个字节?
作为一种解决方法,我目前根本没有使用 struct
,而是使用一些宏来计算数据结构的总大小、分配平面字节数组以及生成索引和位用于访问各个成员的掩码。我想改用 dummy[5].b
这样的语法。
一些编译器似乎有启用位字段打包的选项(如 #pragma pack
),但我在 SDCC 手册中没有找到类似的内容。
恐怕在任何编译器中都不可能。它会为每个结构分配至少一个字节
我会这样做:
typedef struct {
unsigned char a0 : 1;
unsigned char b0 : 2;
unsigned char a1 : 1;
unsigned char b1 : 2;
unsigned char a2 : 1;
unsigned char b2 : 2;
unsigned char a3 : 1;
unsigned char b3 : 2;
unsigned char a4 : 1;
unsigned char b4 : 2;
unsigned char a5 : 1;
unsigned char b5 : 2;
unsigned char a6 : 1;
unsigned char b6 : 2;
unsigned char a7 : 1;
unsigned char b7 : 2;
}data;
data dx;
#define GT(dt,member,bit) ((dt).member ##bit)
void foo()
{
GT(dx,b,5) = 2;
}