在接触PowerPC开发时,难免会碰到大小端转换的问题,PowerPC系统核心是大端的,而像DMA、DSP、PCIE、FPGA都是小端的,所以有必要把它们详细记录一下。我们常常看到“alignment", "endian"之类的字眼, 但很少有C语言教材提到这些概念。实际上它们是与处理器与内存接口,编译器类型密切相关的。考虑这样一个例子:两个异构的CPU进行通信, 定义了这样一个结果来传递消息:
struct Message
{
short opcode;
char subfield;
long message_length;
char version;
short destination_processor;
}message;
用这样一个结构来传递消息貌似非常方便, 但也引发了这样一个问题: 若这两种不同的CPU对该结构的定义不一样, 两者就会对消息有不同的理解。有可能导致二义性。 会引发二义性的有这两个方面:
1.内存地址对齐
2.大小端定义
本文先介绍内存地址对齐和大小端的概念,再回头来看这个例子就会豁然开朗了。
内存地址对齐,英文名为" Byte Alignment"。大部分16位和32位的CPU不允许将字或者长字存储到内存中的任意地址。 比如MPC 83xx系列就不允许将16位的字存储到奇数地址中,将一个16位的字写到奇数地址将引发异常。
实际上, 对于c中的字节组织, 有这样的对齐规则:
1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除