大端小端模式

http://blog.chinaunix.net/uid-1782237-id-2851117.html

所谓的大端模式,是指数据的低位(就是权值较小的后面那几位)保存在内存的高地址中,而数据的高位,保存在内存的低地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;
   所谓的小端模式,是指数据的低位保存在内存的低地址中,而数 据的高位保存在内存的高地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低,和我们的逻辑方法一致。
   为什么会有大小端模式之分呢?这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为 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处理器还可以由硬件来选择是大端模式还是小端模式。
   下面这段代码可以用来测试一下你的编译器是大端模式还是小端模式:   short int x;
char x0,x1;
x=0x1122;
x0=((char*)&x)[0]; //低地址单元
x1=((char*)&x)[1]; //高地址单元
若x0=0x11,则是大端; 若x0=0x22,则是小端......
上面的程序还可以看出,数据寻址时,用的是低位字节的地址


http://blog.163.com/shengrui_step/blog/static/20870918720139103944374/

[杂谈] 计算机中的小端模式和大端模式

我们都知道,内存中存储的是各种变量,各种奇葩东西,不用的变量占用不用的字长,例如在intel X86环境下,一个int占用两个字
 01
2







0x30
0x31 
 0x32 0x33 0x34 0x35 0x360x37 
0x38 
0x39 
节,即16位。然后在这16位上用0或1来表示这个int类型的变量到底是什么数值。那么这样就有两种写法了,在这16位上是从左往右写呢,还是从右往左写呢。这就好比现代人写字从左往右,古人写字从右往左。根据这样两种不同的写法,计算机中就产生了两种模式:小端模式和大端模式。具体来看一个例子:
假设在intel X86环境下,有一个数字,是1539,用二进制就表示为:0000 0110 0000 0011(两个字节)

高八位低八位
0000 0110  0000 0011
   既然计算机以字节为单位,如果这里的一个字节相当于写一个汉字的话,那这个1539在计算机内部就相当于要写两个汉字。怎么写呢,不着急,先介绍 小端模式:按照从低地址到高地址的顺序,依次存放数据的低字节到高字节。 
  高八位低八位
 小端模式: 0000 0110 0000 0011

插入一句:一个数的原数,是高字节在左,低字节在右,当然是这样,因为左边的权值高,2的次方高。学习本篇的时候,要始终记住吧一个个字节作为一个个单位,而不要着眼于位。

我这里高八位标在左边,低八位标在右边,很多地方低八位标左,高八位标右,这个其实是完全一样的,怎么看得舒服就怎么写。
按照定义,低地址放低字节,高地址放高字节,所以低八位放1539的低字节,高八位放1539的高字节。

接下来是 大端模式:按照从低地址到高地址的顺序,依次存放数据的高字节到低字节。
  高八位 低八位
 大端模式: 0000 0011 0000 0110
现在再回头看看,不过就是正着写反着写而已。╮(╯_╰)╭
一般来说,x86 系列 CPU 都是小端模式的字节序,PowerPC 通常是大端模式字节序,还有的CPU能通过跳线来设置CPU工作于小端模式还是大端模式模式。基本上要考察都是intel x86 x64环境,都是小端模式,不会那么坑考冷门的大端模式。。


练习:
0x1234abcd
                  低地址              高地址
小端模式:0xcd  0xab  0x34  0x12
大端模式:0x12  0x34  0xab  0xcd

写出下列程序的执行结果

#include<stdio.h>
main()
{
	char *sz = "0123456789";
	int *p = (int*)sz;
	printf("%x\n",*++p);
}
答案是37363534
 '0''1''2''3''4' '5' '6' '7' '8' '9' 
0x30 0x31  0x32 0x33 0x34 0x35 0x360x37 0x38 0x39 
   int *p = (int*)sz; 这句话的意思是说把这块内存当做int来对待。可以这样理解,数据就在内存中摆着,就看你当成什么来用了。
不管32位还是64位,int都占四个字节,printf那边有个++p,这个p是int型的指针,所以按照int的大小走四个字节
即现在p指向的是:

 '0''1'
'2'
'3' 
'4' 
'5' 
'6' 
'7' 
'8' 
'9' 
0x30
0x31 
 0x32 0x33 0x34 0x35 0x360x37 
0x38 
0x39 
这块内存区域。还记得吗,用的是小端模式,那这个int变量该怎么写?
很明显是:0x37363534(低地址存低字节)
所以用%X输出的话就看到了37363534这个结果了。


写出下列程序执行结果
int a = 0x12345678;
char *p = (char*)(&a);
printf("%x\n",*(p+1));
答案是0x56

判断计算机是大端还是小端:

int i=1;   char *p=(char *)&i;   if(*p==1)         printf("小端模式"); else // (*p == 0)     printf("大端模式");

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值