1.检查小端和大端模式方法

2.大小端模式的判断处理器

3.大端模式和小端模式

4.小端和大端的区别

判断电脑系统大端还是小端,代码判断大端小端

下面的程序可以判断一台机器是大端存储还是小端存储。

[cpp]?view plain?copy

#include<stdio.h>

int?main(int?argc,?char**?argv){

//联合(union)中,所有成员引用的是内存中相同位置,

//由具体成员类型决定了这些位如何被解释

union{

short?s;

char?c[sizeof(short)];

}?un;

un.s?=?0x0102;?//16进制数中,02是低序字节,01是高序字节

if(sizeof(short)==2){

if(un.c[0]==1?&&?un.c[1]==2){

printf("big-endian\n");

}else?if(un.c[0]==2?&&?un.c[1]==1){

printf("little-endian\n");

}else{

printf("unknow\n");

}

}else{

printf("sizeof(short)?=?%d\n",sizeof(short));

}

return?0;

} ?

检查小端和大端模式方法

#include<stdio.h>

union node

{

int a;

char b[4];

};

int main()

{

union node t;

t.a=1;

printf("%d\n",t.b[0]);

printf("%d\n",t.b[1]);

printf("%d\n",t.b[2]);

printf("%d\n",t.b[3]);

}

把int的每个字节读出来。要是第一个字节为0证明是大端模式 第一个字节为1证明是小端模式

大小端模式的判断处理器

定义一联合体.

union A{

int a;

char b[4];

}a;

a.a=1;

if (a.b[0] == 0)

{

//大端

} else {

//小端

}

大端模式和小端模式

通过下列的程序可以确认在某个硬件平台上的某个操作系统是大端还是小端:

VB6: '?注意这个CopyMemory的声明与一般的不一样,'?一般的都是(pDst?As?Any,?pSrc?As?Any,?ByVal?ByteLen?As?Long)'?为了能够逐字节访问u,所以前面两个参数改成了按值传递,配合VarPtr函数获取变量地址Private?Declare?Sub?CopyMemory?Lib?kernel32?Alias?_RtlMoveMemory?(ByVal?pDst?As?Long,?ByVal?pSrc?As?Long,?ByVal?ByteLen?As?Long)Private?Sub?Form_Load()'?VB的Integer占用2个字节!Long才是4个字节'?32位应用程序的指针是4个字节Dim?uptr?As?LongDim?aptr?As?LongDim?bptr?As?LongDim?cptr?As?LongDim?dptr?As?LongDim?u?As?Long'?储存u从低地址到高地址的4个字节Dim?a?As?ByteDim?b?As?ByteDim?c?As?ByteDim?d?As?Byteu?=?367328153?'?十六进制数:15?E4?FB?99uptr?=?VarPtr(u)?'?VarPtr函数是内置函数,但是msdn不说,作用是获取变量的地址aptr?=?VarPtr(a)bptr?=?VarPtr(b)cptr?=?VarPtr(c)dptr?=?VarPtr(d)CopyMemory?aptr,?uptr?+?0,?1?'?将u逐字节按顺序写入a,b,c,dCopyMemory?bptr,?uptr?+?1,?1CopyMemory?cptr,?uptr?+?2,?1CopyMemory?dptr,?uptr?+?3,?1'?Windows系统,英特尔处理器:最后输出的是99?FB?E4?15MsgBox?Hex(a)?&&?Hex(b)?&&?Hex(c)?&&?Hex(d)End?Sub在英特尔处理器,Windows10操作系统上,对话框显示的结果是99 FB E4 15,与直接求出来的16进制值15 E4 FB 99正好相反,所以是小端的。

C++语言(VS2013下,控制台项目): #include?<iostream>using?namespace?std;typedef?unsigned?char?byte;//?转换char(视为整数类型)为16进制字符串void?ChtoHex(byte?Val,?char*?dest){//?辗转相除法,倒序看得到结果byte?tmp?=?Val?%?16;if?(tmp?>=?0?&&?tmp?<=?9){dest[1]?=?'0'?+?tmp;}else?if?(tmp?>=?10?&&?tmp?<=?15){dest[1]?=?'A'?+?tmp?-?10;}tmp?=?(Val/16)?%?16;if?(tmp?>=?0?&&?tmp?<=?9){dest[0]?=?'0'?+?tmp;}else?if?(tmp?>=?10?&&?tmp?<=?15){dest[0]?=?'A'?+?tmp?-?10;}//?设置'\0'dest[2]?=?'\0';}//?主函数int?main(){int?u?=?367328153;?//?原始数据,8位16进制为15?E4?FB?99byte?a,?b,?c,?d;//?u从低地址到高地址的四个字节//?a~d对应的16进制字符串,预留3个字符char?Sa[3],?Sb[3],?Sc[3],?Sd[3];?byte*?k?=?(byte*)&u;a?=?k[0];b?=?k[1];c?=?k[2];d?=?k[3];//?转成16进制字符串ChtoHex(a,?Sa);ChtoHex(b,?Sb);ChtoHex(c,?Sc);ChtoHex(d,?Sd);cout?<<?Sa?<<<<?Sb?<<<<?Sc?<<<<?Sd?<<?endl;system(pause);return?0;}在英特尔处理器,Windows10操作系统上,控制台显示的结果是99 FB E4 15,与直接求出来的16进制值15 E4 FB 99正好相反,所以也证明是小端的。

C语言(VC++6.0,控制台工程): #include?<stdio.h>typedef?unsigned?char?byte;//?转换char(视为整数类型)为16进制字符串void?ChtoHex(byte?Val,?char*?dest){//?辗转相除法,倒序看得到结果byte?tmp?=?Val?%?16;if?(tmp?>=?0?&&?tmp?<=?9){dest[1]?=?'0'?+?tmp;}else?if?(tmp?>=?10?&&?tmp?<=?15){dest[1]?=?'A'?+?tmp?-?10;}tmp?=?(Val/16)?%?16;if?(tmp?>=?0?&&?tmp?<=?9){dest[0]?=?'0'?+?tmp;}else?if?(tmp?>=?10?&&?tmp?<=?15){dest[0]?=?'A'?+?tmp?-?10;}//?设置\0dest[2]?=?'\0';}//?主函数void?main(){int?u?=?367328153;?//?原始数据,8位16进制为15?E4?FB?99byte?a,?b,?c,?d;//?u从低地址到高地址的四个字节//?a~d对应的16进制字符串,预留3个字符char?Sa[3],?Sb[3],?Sc[3],?Sd[3];?byte*?k?=?(byte*)&u;a?=?k[0];b?=?k[1];c?=?k[2];d?=?k[3];//?转成16进制字符串ChtoHex(a,?Sa);ChtoHex(b,?Sb);ChtoHex(c,?Sc);ChtoHex(d,?Sd);printf(%s?%s?%s?%s\n,?Sa,?Sb,?Sc,?Sd);scanf_s(%d,?&a);}在英特尔处理器,Windows10操作系统上,结果跟上面是一样的,输出的16进制数是反序的,证明是小端系统。

C#(VS2013下,控制台项目): using?System;namespace?ConsoleApplication1{class?Program{static?void?Main(string[]?args){int?u?=?367328153;?//?原始数据,8位16进制为15?E4?FB?99byte[]?bytes;//?u从低地址到高地址的四个字节//?获取bytes?=?System.BitConverter.GetBytes(u);Console.WriteLine(bytes[0].ToString(X)?++bytes[1].ToString(X)?++bytes[2].ToString(X)?++bytes[3].ToString(X));Console.ReadLine();}}}在英特尔处理器,Windows10操作系统上,结果跟上面还还是一样的,输出的16进制数是反序的,证明是小端系统。

MDK(Keil5,STM32F407)C语言: #include?stm32f4xx.hint?main(void){?int?u?=?367328153;?//?原始数据15?E4?FB?99int*?k?=?&u;return?0;}编译连接然后下载到开发板上,然后启动调试,通过监视窗口可以看到u的地址,然后在内存窗口可以看到字节序是反序的,所以说明STM32F407是小端的。据某些资料说ARM内核是可以设置大小端的,但是STM32是外设自动进入了小端,似乎是无法调整的。

89C52(Keil5)C语言:

最后来一个大端的例子。手头上没有51的开发板,所以用的是软件仿真。 #include?<reg52.h>int?main(){int?longbit?=?sizeof(long);long?u?=?367328153;?//?原始数据15?E4?FB?99long*?k?=?&u;return?0;}注意看了,C52是8位的处理器,long才是4个字节的,看监视窗口longbit的值就知道了(紫色框)。然后再看内存窗口,就会发现u的存储是跟原始数据给的顺序是一样的,所以C51和C52是大端的!!

小端和大端的区别

大端模式(Big-Endian)又称大端字节序,由于在网络传输中一般使用的是大端模式,所以也叫网络字节序。

在大端模式中,将高位字节放在低位地址,低位字节放在高位地址。

举个例子,数值 0x12345678 ,其中 0x12 这一端是高位字节, 0x78 这一端是低位字节。

该数值的存储顺序是这样的:

大端模式符合我们阅读和书写的方式,都是从左到右的。比如 12345678 ,我们只需要按照从左到右的顺序进行阅读和书写就是大端模式的存储顺序了。

小端模式(Little-Endian)又称小端字节序,由于大多数计算机内部处理使用的是小端模式,所以也叫主机序。

在小端模式中,将高位字节放在高位地址,低位字节放在低位地址。

小端模式比较符合我们人类的思维模式,大的放大的那一边,小的放小的那一边。但是在计算机中存储的顺序与我们看到的顺序是相反的。

对于早期的计算机来说,先处理低位字节效率比较高,因为计算都是从低位开始的,所以大多数计算机内部处理使用的是小端模式。但是计算机发展到现在,计算机的处理器相较于以前已经进步很多了,先处理高位还是低位字节的影响已经可以忽略,但是为了向后兼容,保留了大/小端模式。

大小端模式各有优势:小端模式强制转换类型时不需要调整字节内容,直接截取低字节即可;大端模式由于符号位为第一个字节,很方便判断正负。

大端模式更适合程序员阅读,因为看到的内容与输出的内容是一致的。

计算机在处理数据的时候,只会按照顺序去读取字节,不关心数据是大端模式还是小端模式。

程序在读取到数据后,需要判断计算机的大小端模式,来决定是否需要进行大小端转换。

如果读到的第一个字节是高位字节,那么就是大端模式;反之,如果读到的第一个字节是低位字节,那么就是小端模式。

小端和大端的区别是字节的排列顺序不同。大端(Big-Endian)和小端(Little-Endian)是计算机体系结构中用于描述多字节数据存储顺序的术语。在“大端”模式中,数据的高位字节(即数值上更重要的部分)存储在内存的低地址处,而数据的低位字节则存储在内存的高地址处。这种存储方式与人们阅读数字的习惯相一致,即从左到右,从高位到低位。相反,“小端”模式则将数据的高位字节存储在内存的高地址处,而将数据的低位字节存储在内存的低地址处。这种存储方式与一些处理器和计算机架构的设计有关。