[技术| 编程·课件·Linux] 大端和小端及如何判断!

service · 发布于 2012-09-23 00:33 · 1609 次阅读
4
笔试遇到三次了,所以现在把这个知识点给补上!希望以后能用的到,并且和各位一起共勉!
一、大端与小端、MSB与LSB
在嵌入式开发中,大端(Big-endian)和小端(Little-endian)是一个很重要的概念。假如现有一32位int型数0x12345678,那么其MSB(Most Significant Byte,最高有效字节)为0x12,其LSB (Least Significant Byte,最低有效字节)为0x78,在CPU内存中有两种存放方式:(假设从地址0x4000开始存放)
方式1:
内存地址
0x4000
0x4001
0x4002
0x4003
存放内容
0x12
0x34
0x56
0x78
方式2:
内存地址
0x4000
0x4001
0x4002
0x4003
存放内容
0x78
0x56
0x34
0x12
那么,方式1的存放形似称为大端模式(Big-endian),方式2的存放形似称为小端模式(Little-endian)。即,在大端模式下,数据的MSB存放在低地址;在小端模式下,数据的LSB 存放在低地址。
二、判断大小端的程序。
很多情况下我们都是用一小段测试代码来判断CPU的大小端模式的。
程序1:
int checkEnd()
{
int i=0x12345678;
char *c=(char *)&i;
return(*c==0x12)
}
返回值:大端返回1,小段返回0
程序2:
int checkEnd()
{
union
{
long a;
char b
}u;
u.a = 1;
if (u.b == 1) return 0;
else return 1;
}
返回值:大端返回1,小段返回0

************************************************************************************
附一楼补充内容,扩展一下:
大端模式和小端模式的起源
        关于大端小端名词的由来,有一个有趣的故事,来自于Jonathan Swift的《格利佛游记》:Lilliput和Blefuscu这两个强国在过去的36个月中一直在苦战。战争的原因:大家都知道,吃鸡蛋的时候,原始的方法是打破鸡蛋较大的一端,可以那时的皇帝的祖父由于小时侯吃鸡蛋,按这种方法把手指弄破了,因此他的父亲,就下令,命令所有的子民吃鸡蛋的时候,必须先打破鸡蛋较小的一端,违令者重罚。然后老百姓对此法令极为反感,期间发生了多次叛乱,其中一个皇帝因此送命,另一个丢了王位,产生叛乱的原因就是另一个国家Blefuscu的国王大臣煽动起来的,叛乱平息后,就逃到这个帝国避难。据估计,先后几次有11000余人情愿死也不肯去打破鸡蛋较小的端吃鸡蛋。这个其实讽刺当时英国和法国之间持续的冲突。Danny Cohen一位网络协议的开创者,第一次使用这两个术语指代字节顺序,后来就被大家广泛接受。

小端模式 :强制转换数据不需要调整字节内容,1、2、4字节的存储方式一样。
大端模式 :符号位的判定固定为第一个字节,容易判断正负。

为什么会有大小端模式之分呢?

      这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为8bit。但是在C语言中除了8bit的char之外,还有16bit的short型,32bit的long型(要看具体的编译器),另外,对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如果将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。例如一个16bit的short型x,在内存中的地址为0x0010,x的值为0x1122,那么0x11为高字节,0x22为低字节。对于大端模式,就将0x11放在低地址中,即0x0010中,0x22放在高地址中,即0x0011中。小端模式,刚好相反。我们常用的X86结构是小端模式,而KEIL C51则为大端模式。很多的ARM,DSP都为小端模式。有些ARM处理器还可以由硬件来选择是大端模式还是小端模式。

评分

参与人数 1学分 +6 收起 理由
sissi + 6 原创帖子,对同学们很有帮助!

查看全部评分

共收到 7 条回复
hslx111 · #2 · 2012-9-23 09:22:20  回复 支持 反对
我来补充点有意思的
大端模式和小端模式的起源
        关于大端小端名词的由来,有一个有趣的故事,来自于Jonathan Swift的《格利佛游记》:Lilliput和Blefuscu这两个强国在过去的36个月中一直在苦战。战争的原因:大家都知道,吃鸡蛋的时候,原始的方法是打破鸡蛋较大的一端,可以那时的皇帝的祖父由于小时侯吃鸡蛋,按这种方法把手指弄破了,因此他的父亲,就下令,命令所有的子民吃鸡蛋的时候,必须先打破鸡蛋较小的一端,违令者重罚。然后老百姓对此法令极为反感,期间发生了多次叛乱,其中一个皇帝因此送命,另一个丢了王位,产生叛乱的原因就是另一个国家Blefuscu的国王大臣煽动起来的,叛乱平息后,就逃到这个帝国避难。据估计,先后几次有11000余人情愿死也不肯去打破鸡蛋较小的端吃鸡蛋。这个其实讽刺当时英国和法国之间持续的冲突。Danny Cohen一位网络协议的开创者,第一次使用这两个术语指代字节顺序,后来就被大家广泛接受。

小端模式 :强制转换数据不需要调整字节内容,1、2、4字节的存储方式一样。
大端模式 :符号位的判定固定为第一个字节,容易判断正负。

为什么会有大小端模式之分呢?

      这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为8bit。但是在C语言中除了8bit的char之外,还有16bit的short型,32bit的long型(要看具体的编译器),另外,对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如果将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。例如一个16bit的short型x,在内存中的地址为0x0010,x的值为0x1122,那么0x11为高字节,0x22为低字节。对于大端模式,就将0x11放在低地址中,即0x0010中,0x22放在高地址中,即0x0011中。小端模式,刚好相反。我们常用的X86结构是小端模式,而KEIL C51则为大端模式。很多的ARM,DSP都为小端模式。有些ARM处理器还可以由硬件来选择是大端模式还是小端模式。

评分

参与人数 1学分 +5 收起 理由
service + 5 积极解答同学问题!很热心!加分!

查看全部评分

vividly · #3 · 2012-9-23 16:22:02  回复 支持 反对
int is_little_endian(void)
{
  int x=1;
  char y =(char) x;
  return y;                        /*小端法机器返回1,大端法机器返回0*/
}
fancyboy · #4 · 2012-9-23 17:01:48  回复 支持 反对
原来贤哥是嵌入式的
vazor · #5 · 2012-9-23 20:32:26  回复 支持 反对
对于这类问题不同机器和系统之间的区别,考虑好两个问题就OK:一个是存两个数,看地址是递增还是递减;二是利用不同类型长度不同,看是先存高位还是低位。

评分

参与人数 1学分 +3 收起 理由
service + 3 思路不错!有思路最重要

查看全部评分

maxOrder石 · #6 · 2012-9-24 11:35:48  回复 支持 反对
程序系统设计课后作业啊,
zrdwhhit · #7 · 2012-9-24 22:07:50  回复 支持 反对
收藏了

来自: 软院网·中科大 iPhone客户端
来自: iPhone客户端
vazor · #8 · 2012-9-25 01:15:04  回复 支持 反对
本帖最后由 vazor 于 2012-9-25 01:16 编辑

既然跟我加分了。。。我就找个例子给大家强化一下
[C] 纯文本查看 复制代码
int i;
char c;
for (i = 0; i < 5; ++i)
{
    scanf("5d", &c);
    printf("%d ", i);
}
putchar('\n');

大家可以先思考思考结果,再来运行。
回帖
B Color Image Link Quote Code Smilies
Command + Enter
快速回复 返回顶部 返回列表