大多数处理器中内存是可以以字节为单位进行寻址的,当数据类型(int, long)大于1个字节时,其所占用就的字节在内存中的顺序存在两种模式,分别是小端模式(little endian)和大端模式(big endian)。小端模式低位字节存放在低地址,大端模式高位字节存放在低地址。
在一个32位处理器上,一个类型为int的endian_id变量占用4个字节。假设endian_id位于0x10000内存地址处,则小端模式的处理器上其个字节如下图所示:
大端模式的处理器上各字节如下图所示:
图中的LSB是指最低有效位(Little Significant Bit),MSB是指最高有效位(Most Significant Bit)。
下面用一个示例程序来展示字节序在编程中的重要性。如果在小端模式的处理器上该运行程序会输出正确的运行结果,在大端模式的处理器上将输出错误的结果。
如上图我是在Linux系统里面运行得到的结果(Linux是小端模式)。
下面分析一下为什么同一个程序在不同字节序的处理器上运行的结果为什么会不一样,下图是说明了在小端模式下main()调用foo()时module_id变量中值得变化过程。注意,foo()函数的参数是以指针的形式传递的,所以在main()中module_id变量的起始地址如果是0x10000,那么传入到foo()函数后_p_module_id变量指向的地址也是0x10000。
从上图中可以看到,小端模式下并不存在问题,这与示例程序是相吻合的。下面我们在展示一下在大端模式的处理器中运行的情形,从图中了解为什么会出现问题
从这个示例程序中我们可以看出,由于处理器两种字节序的存在,如果指针的传递类型不匹配,有可能导致运行的结果出错,因此在软件开发过程中指针应当严格按照所需类型进行传递。
更多的精彩内容请关注微信公众号“Linux嵌入式”