你的位置:首页 > 软件开发 > 操作系统 > 也谈linux中cpu大小端问题

也谈linux中cpu大小端问题

发布时间:2017-11-18 00:00:29
内存对齐问题之大小端对齐问题郝东东写 所谓的大小端问题,也就是字节序。处理器(CPU)对内存数据操作有两种模式:读和写。这样,处理器在读写一个多字节内存的时候,高字节是在内存的高地址还是低地址就是一个问题,不同的大小端模式可能有不同的结果。当处理器读写指令针对数据不一致的时候 ...

内存对齐问题之大小端对齐问题

郝东东

 

所谓的大小端问题,也就是字节序。处理器(CPU)对内存数据操作有两种模式:读和写。这样,处理器在读写一个多字节内存的时候,高字节是在内存的高地址还是低地址就是一个问题,不同的大小端模式可能有不同的结果。

当处理器读写指令针对数据不一致的时候就涉及到大小端问题,例如:将0x7654321放入内存里,然后在内存首地址用单字节读取命令,这就涉及到处理器是大端还是小端。对于小端处理器,写内存的时候会将内存的低地址处放入数据源的低字节,在内存的高地址处放入数据源的高字节;大端模式则刚好相反。这个可以参照下面这个例子:

 

 1 Char c1,c2,c3,c4; 2  3 Unsigned char *p; 4  5 Unsigned long a=0x76543210; 6  7 P=(unsigned char *)&a; 8  9 C1=*p;10 11 C2=*(p+1);12 13 C3=*(p+2);14 15 C4=*(P+3);

这样的话,可以输出这四个值,在小端处理器运行的时候:c1=0x10;c2=0x32;c3=0x54;c4=0x76;这是由于在储存a的时候,需要4个连续的字节,小端模式最低的字节将被放置在内存的最低位。0x10被放置在第一个字节。同理大端模式则相反。C4=0x10;

下面介绍几种方法,可以直接判断我们的电脑是什么模式储存数据:第一种方案:利用联合体。程序如下:

 1 #include<stdio.h> 2  3 #include<stdlib.h> 4  5 int cpu_return() 6  7 { 8  9  union perk10 11  {12 13  int a;14 15  char b;16 17  }c;18 19 c.a==1;20 21 return(c.b==1);22 23 }24 25 26 27 int main()28 29 {30 31 printf("%d\n",cpu_return());32 33 }

返回0则是小端模式,1是大端模式。

 

第二种方案:构造共用体,用长整型来访问,依次输出每个字节,程序如下:

 1 #include<stdio.h> 2  3 #include<stdlib.h> 4  5 typedef struct byte_4 6  7 { 8  9 unsigned char byte0;10 11 unsigned char byte1;12 13 unsigned char byte2;14 15 unsigned char byte3;16 17 }byte4;18 19 typedef union data3220 21 {22 23 unsigned long data;24 25  byte4 databyte;26 27 }data_32;28 29 int main(void)30 31 {32 33  data_32 a;34 35 a.data=0x11223344;36 37 printf("databyte(0,1,2,3):(%x,%x,%x,%x)\n",a.databyte.byte0,a.databyte.byte1,a.databyte.byte2,a.databyte.byte3);38 39 return 0;40 41 }

小端输出为:databyte(0,1,2,3):(44,33,22,11)

大端输出为:databyte(0,1,2,3):(11,22,33,44)

 

第三种方案直接看最低位储存的值来判断:

 1 #include<stdio.h> 2  3 #include<stdlib.h> 4  5 int testcpu() 6  7 { 8  9 unsigned int x=1;10 11 if(1==*(unsigned char *)&x)12 13 printf("Little Endian\n");14 15 else16 17 printf("Big Endian\n");18 19 return(1==*(unsigned char *)&x);20 21 }22 23 int main()24 25 {26 27 printf("CPU:%d\n",testcpu());28 29 return 0;30 31 }

小端返回1,大端返回0; 

 

最后,linux中网络编程中要特别注意大小端问题,因为网络字节序和本机字节序通常是需要转换的,比如判断一个udp报文是否为dhcp报文,需要将报文中的udp端口进行字节序转换,通常调用ntohs去转换后才可以判断和赋值。

 

 

海外公司注册、海外银行开户、跨境平台代入驻、VAT、EPR等知识和在线办理:https://www.xlkjsw.com

原标题:也谈linux中cpu大小端问题

关键词:linux

*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。

可能感兴趣文章

我的浏览记录