Motorola & Intel, Big Endian & Little Endian,大端和小端

在谈通讯相关编程的时候,我们需要对存储格式和机制加以留意。

1、由来

1980年,Danny Cohen在其著名的论文"On Holy Wars and a Plea for Peace"中为了平息一场关于在消息中字节该以什么样的顺序进行传送的争论而引用了该词。该文中,Cohen非常形象贴切地把支持从一个消息序列的最高位开始传送的那伙人叫做Big-Endians,支持从最低位开始传送的相对应地叫做Little-Endians。此后Endian这个词便随着这篇论文而被广为采用。(摘自百度百科Endian词条)

2、术语

小端 = Little-Endians = Intel Mode:低字节在前(左),高字节在后(右)

大端 = Big-Endians = Motorola Mode:高字节在前(左),低字节在后(右)

3、说明

在一个8位的字节中,二进制数以高位在左,低位在右排列,如同我们书写十进制数的格式。

在表达一个多字节的整数时,就出现大端和小端的分歧,这主要与CPU的架构有关。Intel系列和ARM系列均采用小端,KEIL C51系列均采用大端。

4、应用协议

在进行计算机通讯编程时,行走于网络中的数据来自不同的设备,根据通讯协议,我们需要对其进行转换。

比较多的工业传输协议,例如串口协议,CANOPEN和MODBUS协议等。广泛用于汽车,传感器和控制的数据传输方面。

在CAN数据结构中,CANID是固定的小端结构,而8个字节的Data部分则是自定义,协议记录在BDC文件中。

5、转换方法

以下为Delphi代码,但是使用的函数均为Windows的API函数。

方法一,使用Windows.unit的makeword和makelong函数

type
  Tbyte4: array [0..3] of byte;

  function Convert(Value: longword): longword;

implementation

function Convert(Value: longword): longword;
var
  myData: ^Tbyte4;
begin
  myData1 := @Value;
  Result := makelong(makeword(myData^[3], myData^[2]), makeword(myData^[1], myData^[0]));
end;

方法二,使用Winsock.unit的htons和htonl函数,这是最经典的代码

function Convert(Value: longword): longword;
begin
  Result := htonl(Value);
end;
function Convert(Value: word): word;
begin
  Result := htons(Value);
end;

这里,htons()函数是将一个无符号的短整形数(16位)值转换成网络字节顺序,其实就是将小端转成大端。同理htonl()用于无符号长整形(32位)。

需要注意的是,htons()用于将主机短整数转换成网络字节顺序,反过来,则使用ntohs()函数。htonl()则对应ntohl()。

方法三,了解上述原理后,不妨自己用指针写个更加高效的程序。

时间: 2024-11-10 13:35:02

Motorola & Intel, Big Endian & Little Endian,大端和小端的相关文章

大端和小端(big endian little endian)

一.大端和小端的问题 对于整型.长整型等数据类型,Big endian 认为第一个字节是最高位字节(按照从低地址到高地址的顺序存放数据的高位字节到低位字节):而 Little endian 则相反,它认为第一个字节是最低位字节(按照从低地址到高地址的顺序存放据的低位字节到高位字节). 例如,假设从内存地址 0x0000 开始有以下数据:  0x0000         0x0001       0x0002       0x0003  0x12            0x34          

大端和小端(Big endian and Little endian)

一.大端和小端的问题 对于整型.长整型等数据类型,Big endian 认为第一个字节是最高位字节(按照从低地址到高地址的顺序存放数据的高位字节到低位字节):而 Little endian 则相反,它认为第一个字节是最低位字节(按照从低地址到高地址的顺序存放据的低位字节到高位字节). 例如,假设从内存地址 0x0000 开始有以下数据:  0x0000         0x0001       0x0002       0x0003  0x12            0x34          

【网络编程系列】一:字节顺序的大端与小端表示法

一.字节序 字节序,也就是字节的顺序,指的是多字节的数据在内存中的存放顺序. 在几乎所有的机器上,多字节对象都被存储为连续的字节序列.例如:如果C/C++中的一个int型变量 a 的起始地址是&a = 0x100,那么 a 的四个字节将被存储在存储器的0x100, 0x101,0x102, 0x103位置. 根据整数 a 在连续的 4 byte 内存中的存储顺序,字节序被分为大端序(Big Endian) 与 小端序(Little Endian)两类. 然后就牵涉出两大CPU派系: Motoro

字节存储排序:大端和小端的判别及转换

当前的存储器,多以byte为访问的最小单元,当一个逻辑上的地址必须分割为物理上的若干单元时就存在了先放谁后放谁的问题,于是端(endian)的问题应运而生了,对于不同的存储方法,就有大端(big-endian)和小端(little- endian)两个描述. 字节排序按分为大端和小端,概念如下 大端(big endian):低地址存放高有效字节 小端(little endian):低字节存放地有效字节 现在主流的CPU,intel系列的是采用的little endian的格式存放数据,而moto

我如何确定一个机器的字节顺序是大端还是小端?

通常的技巧是使用一个指针: int x = 1; if(*(char *)&x == 1) printf("little-endian\n"); else printf("big-endian\n"); 或者一个union: union { int i; char c[sizeof(int)]; } x; x.i = 1; if(x.c[0] == 1) printf("little-endian\n"); else printf(&qu

关于byte[]字节传输的大端和小端小议

当前的存储器,多以byte为访问的最小单元,当一个逻辑上的地址必须分割为物理上的若干单元时就存在了先放谁后放谁的问题,于是端(endian)的问题应运而生了,对于不同的存储方法,就有大端(big-endian)和小端(little- endian)两个描述. 字节排序按分为大端和小端,概念如下 大端(big endian):低地址存放高有效字节 小端(little endian):低字节存放地有效字节 现在主流的CPU,intel系列的是采用的little endian的格式存放数据,而moto

【转】如何判断CPU是大端还是小端模式

原文网址:http://blog.csdn.net/ysdaniel/article/details/6617458 如何判断CPU是大端还是小端模式 http://blog.sina.com.cn/s/blog_66a61f310100i7m0.html MSB:Most Significant Bit  ------- 最高有效位    LSB:Least Significant Bit ------- 最低有效位 大端模式(big-edian) big-endian:MSB存放在最低端的地

变量在内存中的存储方式-----“大端”和“小端”

"大端"和"小端"可以追溯到1726年的Jonathan Swift的<格列佛游记>,其中一篇讲到有两个国家因为吃鸡蛋究竟是先打破较大的一端还是先打破较小的一端而争执不休,甚至爆发了战争.1981年10月,Danny Cohen的文章<论圣战以及对和平的祈祷>(On holy wars and a plea for peace)将这一对词语引入了计算机界(<程序设计实践>第9章).这么看来,所谓大端和小端,也就是big-endia

大端与小端,大尾与小尾,高尾端与低尾端,主机字节序与网络字节序

概念剖析 一时记忆与理解大端.小端的概念很容易,但时间一长,对于相似的概念人类的记忆向来是模糊的,甚至是换位的.所以除非你的记忆非常牢靠,否则借助大端和小端这样的名字,你很难将概念与内容联系紧密. 也有文章提到用大尾与小尾的概念,个人觉得这个概念还是没有解决存储概念中的基本问题,大与小还是没有脱离以前的概念,但是引入了尾的概念,已经比大端与小端要更清晰一点. 目前对于记忆大小端,我觉得这篇文章中提到的高尾端/低尾端名词记忆方法比较科学.形象.实话说,当时计算机科学著作翻译Big Endian与S