汉扬编程 C语言入门 嵌入式C语言中针对大小端的处理

嵌入式C语言中针对大小端的处理

我在上一个专题中,讲联合体的应用时,有朋友提到了关于大小端的问题。我感觉我在回复里也没有讲得太清楚,我就专门再开一个专题来探讨一下。同时在这里,也欢迎大家一起来讨论,也欢迎大家关注我的头条号。

嵌入式C语言中针对大小端的处理

首先我们先来搞清楚一个问题,

为什么会有大小端的区别?

对于一个处理器来讲,一般是一个字节(byte)的存储空间对应一个唯一的地址。8位的处理器不存在大小端的问题,这个问题主要针对的是16位和32位的处理器。以32位处理器为例,我们说的32位,实际就是指的处理器的地址总线是32位的。也就是说,在32位处理器的存储空间里,每一个字节对应一个32位地址,当然这个地址是唯一的。那么我们在处理一个字(word)的时候,也就是4个字节(byte),要把这4个字节分别放入4个连续的地址中,一般也就是两种方式。一种低位在前,byte0放在低地址中,再从byte1到byte3依次按顺序往后放;另一种高位在前,byte3放在低地址中,再从byte2到byte0依次按顺序往后放。前面这一种方式,就叫做小端模式;后面这一种方式,就叫做大端模式。

上图就是数值0x1,在小端模式和大端模式下的不同存储方法。

大小端模式取决于芯片内核

由此,我们可以看出大小端不同的模式,完全取决于芯片的内核。各个芯片设计公司,对此有各自自己的玩法。这也不能完全怪人家,为什么不统一标准。现实中,有好多设计有时候是设计者刻意为之,后者往往为了区别于前者的设计,而采取另外一条路,实际上是殊途同归。但是这样做却可以规避一个叫做“专利”的东西。

针对大小端数据结构的定义

为了程序能够跨平台使用,我们也经常定义这样的数据结构,

typedef union{ t_uint32 Word; struct { #if ENDIAN_MODE == BIG_END t_uint8 Byte3; t_uint8 Byte2; t_uint8 Byte1; t_uint8 Byte0; #else t_uint8 Byte0; t_uint8 Byte1; t_uint8 Byte2; t_uint8 Byte3; #endif }Byte; }un_uint32;如果是大端模式,你可以将ENDIAN_MODE定义成BIG_END,否则你就定义成LITTLE_END,你可以选择默认小端模式。现在基本上是arm内核大行其道,arm内核既支持小端模式又支持大端模式,但是也是默认小端模式。这也算是回答了网友提出来的问题。

与大小端问题类似的,还有LSB和MSB的问题,在这里也一起讨论一下。

数据通讯中LSB和MSB

在数据通讯中,一般数据流有两种通讯方式:LSB和MSB。LSB,低位在前,也就是低位先发;MSB,高位在前,也就是高位先发。我看有些文章里,把这个问题和大小端问题,混为一谈,我个人其实不太认同。一个是针对数据通信,一个是针对数据存储,虽然都是在定义先后顺序。你要是非要说数据存储还不是由数据传输决定的,先传输谁就先存储谁,那也算是这两个问题在一定程度上的统一。

但是, 我还是觉得把这两个问题分开来对待还是比较好。如果硬要把这两个问题都归类到一起,那也是在完全理解各自问题的基础之上。

用C语言,如何判断主机是 大端还是小端(字节序)

所谓大端就是指高位值在内存中放低位地址,所谓小端是指低位值在内存中放低位地址。比如 0x12345678 在大端机上是 12345678,在小端机上是 78564312,而一个主机是大端还是小端要看CPU类型以及运行在上面的操作系统。同一款CPU在不同的操作系统使用的大小端情况是不同的。当然我们通常使用的 x86 + windows是小端。

测试大小端一般使用 union的特性。union是一个联合体,所有变量公用一块内存,只是在不同的时候解释不同。其在内存中存储是按最长的那个变量所需要的位数来开辟内存的。

#include <stdio.h>#include <stdbool.h>union { int number; char s;} test;bool testBigEndin() { test.number = 0x01000002; return (test.s == 0x01);}int main(int argc, char **argv) { if (testBigEndin()) { printf(\”big\”); } else { printf(\”small\”); }}我的 Mac输出: small

其中 union的实际内存长度是int,即一个字,在32位机上是32位。而char是一个Byte(8位),只会取第一个低地址字节。所以它的值可以用来判断大小端。

本文来自网络,不代表汉扬编程立场,转载请注明出处:http://www.hyzlch.com/cjia/6846.html

嵌入式C语言之——测试大小端模式详解

c++和c语言之间有什么区别

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注

返回顶部