大端小端及内存分布


大端小端辨别方法:

#include <iostream>
using namespace std;

int ChackCPUendian()
{
	//联合体,共用同一块内存
	//存放顺序是所有成员都从低地址开始存放
	union
	{
		unsigned int a;
		unsigned char b;
	}un;
	un.a = 1;
	//如果b=0,说明为大端
	//若果b=1,说明为小端
	return (un.b == 1); 
}

int main(void)
{
	cout <<"CPU:"<< ChackCPUendian() << endl; //1 小端模式

	return 0;
}



通过Debug可以看到,

从调试的地址分布可知:

由于内存从上到下,显示的地址是从低到高。

所以内存从左向右,地址是从低到高。



unsigned int a 的地址从0x0080f850开始占用4个字节.

整数1的16进制为:


  数值          数值

  高位   ->   低位

  00 00 00 01

而在内存中:

        地地址 -> 高地址

        01 00 00 00


结论: 数值低位存储在低地址,数值高位存储在高地址,由此可知为小端模式


下面就上面得到的结论,再分析一个例子:(只是a的取值不同,其他的都与上面一样)

unsigned int a 的地址从0x0113FA2C开始占用4个字节.

整数123456的16进制为:

数值   数值

高位 -> 低位

00 01 e2 40

而在内存中:

        地地址 -> 高地址

        40  e2  01 00


结果与上面的结论一致!



  x86的CPU使用的是LE(Windows中称为“主机字节序”),而SocksAddr中使用的则是BE(就是“网络字节序”),所以在使用网络编程时需要使用htns,htnl,nths,nthl来倒字节序。

其实对汇编熟了就清楚了,惨,我的汇编很惨的

LE little-endian 
最符合人的思维的字节序 
低地址存储值的低位 
高地址存储值的高位 
怎么讲是最符合人的思维的字节序,是因为从人的第一观感来说 
低位值小,就应该放在内存地址小的地方,也即内存地址低位 
反之,高位值就应该放在内存地址大的地方,也即内存地址高位 

BE big-endian 
最直观的字节序 
低地址存储值的高位 
高地址存储值的低位
 
为什么说直观,不要考虑对应关系 
只需要把内存地址从左到右按照由低到高的顺序写出 
把值按照通常的高位到低位的顺序写出 
两者对照,一个字节一个字节的填充进去 


例子:在内存中双字0x01020304(DWORD)的存储方式 

内存地址 
4000 4001 4002 4003 
LE 04 03 02 01 
BE 01 02 03 04 

MSDN中关于LE和BE的解释
Byte Ordering Byte ordering Meaning 
big-endian The most significant byte is on the left end of a word. 
little-endian The most significant byte is on the right end of a word. 
这里这个最重要的字节可以解释成值的最高位,如果换成是钱的话就是最值钱的那一位 
比如我有1234元人民币,最值钱的是1000元,最不值钱的是4元,那么这个1就是最重要的字节

Big endian machine: It thinks the first byte it reads is the biggest.
Little endian machine: It thinks the first byte it reads is the littlest.
举个例子,从内存地址0x0000开始有以下数据
0x0000    0x12
0x0001    0x34
0x0002    0xab
0x0003    0xcd
如果我们去读取一个地址为0x0000的四个字节变量,若字节序为big-endian,则读出
结果为0x1234abcd;若字节序位little-endian,则读出结果为0xcdab3412.
如果我们将0x1234abcd写入到以0x0000开始的内存中,则结果为
                big-endian    little-endian
0x0000    0x12              0xcd
0x0001    0x23              0xab
0x0002    0xab              0x34
0x0003    0xcd              0x12
x86系列CPU都是little-endian的字节序.

猜你喜欢

转载自blog.csdn.net/mayi_xiaochaun/article/details/50083373
今日推荐