zoukankan      html  css  js  c++  java
  • 大端和小端

    一、简述

    1.1大端小端区别

    • 根据计算机中数据在硬件(内存/寄存器)中存储顺序(存储方式),可以分为大端小端
    • 大端:低地址存储高位数据。
    • 小端:低地址存储低位数据。

    举例:0x123456在内存中的存储方式

      1 - 大端模式:
      2 低地址 -----> 高地址
      3 0x12 | 0x34 | 0x56
      4 
      5 
      6 - 小端模式
      7 低地址 -----> 高地址
      8 0x56 | 0x34 | 0x12


    1.2大端小端来源

    端模式(Endian)的这个词出自JonathanSwift书写的《格列佛游记》。这本书根据将鸡蛋敲开的方法不同将所有的人分为两类,从圆头开始将鸡蛋敲开的人被归为BigEndian,从尖头开始将鸡蛋敲开的人被归为LittileEndian。小人国的内战就源于吃鸡蛋时是究竟从大头(Big-Endian)敲开还是从小头(Little-Endian)敲开。在计算机业BigEndian和LittleEndian也几乎引起一场战争。在计算机业界,Endian表示数据在存储器中的存放顺序。

    • 一开始是由于不同架构的CPU处理多个字节数据的顺序不一样,比如x86的是小段模式,KEIL C51是大端模式。但是后来互联网流行,TCP/IP协议规定为大端模式,为了跨平台通信,还专门出了网络字节序和主机字节序之间的转换接口(ntohs、htons、ntohl、htonl)
    • 大小端模式各有优势:小端模式强制转换类型时不需要调整字节内容,直接截取低字节即可;大端模式由于符号位为第一个字节,很方便判断正负。

    1.3大端、小端设备

    • 互联网使用的网络字节顺序采用大端模式进行编址,而主机字节顺序根据处理器的不同而不同。
    • 大端模式处理器的字节序到网络字节序不需要转换;而小端模式处理器的字节序到网络字节必须要进行转换。
    小端设备 大端设备
    Pentuim处理器 PowerPC处理器
    x86机  
    IBM,Motorola(PowerPC),Sun的机器  
    ARM、Alpha、Motorola(PowerPC),即能工作于大端又能工作于小端,需要具体参考处理器手册。


    • 大部分用户的操作系统(如windows, FreeBsd,Linux)是Little Endian的。少部分是Big Endian,如MAC OS 。Little Endian还是Big Endian与操作系统和芯片类型都有关系。
    • Linux系统中,可以在/usr/include/中(包括子目录)查找字符串BYTE_ORDER(或_BYTE_ORDER,__BYTE_ORDER),确定其值。
    • BYTE_ORDER中文称为字节序。这个值一般在endian.h或machine/endian.h文件中可以找到,有时在feature.h中,不同的操作系统可能有所不同。

    二、判断大端小端

    原理:

    1. C/C++中short占2个字节,char占1个字节。0xFF00存入short变量。
    2. 取short变量中的一个字节数据存入char变量。
    3. 判断char变量地址和short变量地址关系。
    4. 如果char地址比short地址更大,说明从short变量取的数据是高地址数据。
    5. 判断char数据是0x00还是0xFF,从而判断出当前系统是大端还是小端。

    测试大端小端代码(C++):

      1 #include <iostream>
      2 
      3 
      4 
      5 using namespace std;
      6 
      7 int main()
      8 {
      9 
     10 	int intData(0xFFFF0000);
     11 	short *shortData = (short*)(&intData);
     12 
     13 	std::cout << "intData address:\t";
     14 	std::cout << &intData << endl;
     15 
     16 	std::cout << "shortData address:\t";
     17 	std::cout << shortData << endl;
     18 
     19 	//获取当前数据地址前一个地址数据和之后一个数据
     20 	short *low = shortData - 1;
     21 	short *high = shortData + 1;
     22 
     23 	//如果之前一个数据和之后一个数据相等,则没有办法判断,此时需要重新检测
     24 	if (*low == *high)
     25 	{
     26 		std::cout << "Please check again!\n";
     27 		getchar();
     28 		return 0;
     29 	}
     30 
     31 	//临时short变量和其地址内容比较使用
     32 	//注意不能直接用0xFFFF和short直接比较,否则有时出错,会把0xFFFF看作int比较
     33 	short temp = 0xFFFF;
     34 
     35 	//当前地址的内容是高位数据
     36 	if (*shortData == temp)
     37 	{
     38 		temp = 0x0000;
     39 		//*shortData地址是高位地址
     40 		if (*low == temp)
     41 		{
     42 			std::cout << "otherPartData addr:\t";
     43 			std::cout << low << endl;
     44 			std::cout << "====================" << endl;
     45 
     46 			std::cout << "shortData is:\t\t";
     47 			std::cout << hex << *shortData << endl;
     48 			std::cout << "otherPartData is:\t";
     49 			std::cout << hex << *low << endl;
     50 			std::cout << "====================" << endl;
     51 
     52 			std::cout << "Little endian!\n";
     53 		}
     54 		//*shortData地址是低位地址
     55 		if (*high == temp)
     56 		{
     57 			std::cout << "otherPartData addr:\t";
     58 			std::cout << high << endl;
     59 			std::cout << "====================" << endl;
     60 
     61 			std::cout << "shortData is:\t\t";
     62 			std::cout << hex << *shortData << endl;
     63 			std::cout << "otherPartData is:\t";
     64 			std::cout << hex << *high << endl;
     65 			std::cout << "====================" << endl;
     66 
     67 			std::cout << "Big endian!\n";
     68 		}
     69 	}
     70 	//当前地址存储低位数据
     71 	else
     72 	{
     73 		temp = 0xFFFF;
     74 		//*shortData地址是高位地址
     75 		if (*low == temp)
     76 		{
     77 
     78 			std::cout << "otherPartData addr:\t";
     79 			std::cout << low << endl;
     80 			std::cout << "====================" << endl;
     81 
     82 			std::cout << "shortData is:\t\t";
     83 			std::cout << hex << *shortData << endl;
     84 			std::cout << "otherPartData is:\t";
     85 			std::cout << hex << *low << endl;
     86 			std::cout << "====================" << endl;
     87 
     88 			std::cout << "Big endian!\n";
     89 		}
     90 		//*shortData地址是低位地址
     91 		if (*high == temp)
     92 		{
     93 			std::cout << "otherPartData addr:\t";
     94 			std::cout << high << endl;
     95 			std::cout << "====================" << endl;
     96 
     97 			std::cout << "shortData is:\t\t";
     98 			std::cout << hex << *shortData << endl;
     99 			std::cout << "otherPartData is:\t";
    100 			std::cout << hex << *high << endl;
    101 			std::cout << "====================" << endl;
    102 
    103 			std::cout << "Little endian!\n";
    104 		}
    105 	}
    106 	getchar();
    107 	return 0;
    108 
    109 }


    Window系统运行结果:

      1 intData address:        010FFE70
      2 shortData address:      010FFE70
      3 otherPartData addr:     010FFE72
      4 ====================
      5 shortData is:           0
      6 otherPartData is:       ffff
      7 ====================
      8 Little endian!
      9 




    三、相关参考

  • 相关阅读:
    Boot-Repair&usb_repair
    Introducing ASLR for FreeBSD
    node.js操作Cookie
    Docker常见仓库MySQL
    Docker常见仓库CentOS
    Docker常见仓库Ubuntu
    Docker常见仓库Node.js
    Docker常见仓库WordPress
    Docker常见仓库Nginx
    Docker命令查询
  • 原文地址:https://www.cnblogs.com/mehome/p/15813395.html
Copyright © 2011-2022 走看看