对于思考小端和大端字节顺序

最近,该公司希望改变核心处理器,由小端处理器ARM为大端处理器POWERPC。bootloader以及kernel移植的工作对我来说,这是一个非常具有挑战性的工作。我很兴奋。

如此一来。当今主流的嵌入式处理器(MIPS ARM PPC)也都算接触过啦。

这几天開始动手做移植,首先要解决的是大小端的差异,进过学习思考,感觉大小端还是非常有研究的必要。自己的思考总结记录在此,与大家分享,以备后用。

从网上能够查到的大小端的解释,小端是低端数据存放在低端地址。大端是高端数据存在低端地址。大小端真的就这么简单吗,不是这种。

字节序大端小端是针对超过一个byte的数据类型在内存中的存储布局来讲的。

对象是数据类型的存储布局,为什么要超过一个byte呢,这涉及到内存寻址,内存寻址的最小单位就是byte,一个byte内的数据排布顺序是固定的(小端)。

打个例如。拿我们自己来说。有一句4个字的话,我们是从右向左读。还是从左向右读,这就是我们的字节序啊。

所以对于处理器在操作超过一个byte的数据类型时。怎样排布数据在内存中的顺序,就由其字节序来决定。

从更底层的数据总线来说,能够这样理解:

对于小端处理器,假设要寻址一个word型数据,处理器首先由地址总线发出地址,之后对于由32位数据总线(32位处理器)返回的数据,小端处理器觉得0-7位数据线是低端数据,而24-31位数据线为高端数据。

  相反,对于大端处理器,寻址一个word型数据,处理器对于数据线返回的数据,觉得24-31位数据线为低端数据,而0-7位数据线为高端数据。

字节序大小端还远没有这么简单。对于字节序的理解,我认为能够分为2种情况:

(1)操作内存

首先说明内存本身是没有字节序一说的,可是对于内存中相同一段数据。小端处理器读出来的数据意义和大端处理器读出来的数据意义是不同的。所以其存储数据的顺序是由处理器字节序来决定的。

操作内存,无非就是读和写。

那这里又能够分为2种情况。

一种是处理器读处理器写。也就是处理器主动发起对于内存的读写,由于使用同一处理器。採用相同的字节序去读写同一数据(改动其值。进行位操作等)是没有区别的。唯一的区别是在对于同一段内存。读写时操作了不同的数据类型。这样的情况就不细说了,由于如今网上大部分关于大小端的文章都会解释这个问题,这也是验证处理器是大端还是小端非常好的方法。

还有一种是还有一主设备与处理器异步的操作了内存。如DMA,假如处理器由小端改为大端,而外设是小端(我这次的移植就是这样的情况),在外围硬件设计不变的情况下(处理器0-31数据线与外设0-31数据线一一相应)。外设DMA写入内存的数据,由处理器读取回来。数据就已经被翻转了,已经失去了原来的意义。这也是做大小端移植须要注意的一点。

移植研究发现,对于DMA来说,操作数据不涉及字节序问题。DMA操作的数据buffer对于处理器来说,也不具有数据类型意义(不须要用word或short来操作,按byte就能够)。

因此对于内存的操作。仅仅要读写时数据类型一致。就不用操心字节序问题。

(2)操作寄存器

如今大部分外设控制器寄存器都是小端设计(这里的设计是指寄存器描写叙述是小端的,数据排布也是小端的)。寄存器也能够分为2种。

一种是位意义的寄存器,这样的寄存器的每一位都有意义,可能是某种功能的开关,这样的寄存器在外设中很常见。对于这类寄存器,小端处理器操作没有区别。由于字节序一致,可是对于大端处理器,其获得寄存器数据是翻转的,所以对于每一位的定义也是翻转的,只是我们能够通过改动软件上(如kernel)对寄存器的位宏定义来获取其正确的位意义,这一点在做大小端移植时须要注意。

还有一种是数据意义的寄存器,这样的寄存器上存储的是有意义的数据,如串口收发数据寄存器。网卡DMA描写叙述符首地址寄存器等。

对于大端处理器,该类寄存器是无法通过改动位宏定义来保证正确。由于其是一个总体数据,这样的寄存器仅仅能是在获取其值后将数据再翻转(大端转小端)。来获取寄存器中原有意义的数据,在进行操作。

可是假设是这种改动,就有一个原子操作的问题了,由于读写寄存器本来是由一条指令完毕的,可是如今却加入了翻转操作。在进行读写指令,这就不能保证寄存器读写的原子性。

在高性能。中断频发,进程不停切换的操作系统下。就有可能产生问题。

对于这个问题。也能够在硬件上进行协作,如将处理器的(0-7)(8-15)(16-23)(24-31)与外设的(0-7)(8-15)(16-23)(24-31)进行反接,可是这样也可能有问题。如对于大于1byte却小于4byte的数据,处理器怎样获取的问题。

这些在由小端到大端移植的问题我还在探索和学习中。还是非常有意思的。

只是对于本来设计为大端,寄存器描写叙述也是大端的外设,与大端处理器相连,就不会有这些问题。

也就是说外围设备和处理器的字节顺序相同。可避免这些难题

版权声明:本文博客原创文章,博客,未经同意,不得转载。

时间: 2024-08-01 01:56:58

对于思考小端和大端字节顺序的相关文章

对于字节序小端和大端的思考

最近公司处理器要换核,由小端处理器ARM换成大端处理器POWERPC,bootloader以及kernel的移植工作交给了我,这是一个很有挑战的工作,自己也非常兴奋. 如此一来,当今主流的嵌入式处理器(MIPS ARM PPC)也都算接触过啦. 这几天开始动手做移植,首先要解决的是大小端的差异,进过学习思考,感觉大小端还是很有研究的必要,自己的思考总结记录在此,与大家分享,以备后用. 从网上可以查到的大小端的解释,小端是低端数据存放在低端地址,大端是高端数据存在低端地址.大小端真的就这么简单吗,

大端/小端,高字节/低字节,高地址/低地址,移位运算

其实大端小端的概念比较好理解的,大端:数据的高字节存放在内存的低地址中. 数组的声明方式是从左往右,地址逐渐增大. int8_t a[] = { 1, 2, 3 }; for (int i = 0; i < 3; i++) printf("a[%d]: %p\n", i, &a[i]); a[0]: 0x7ffce52cf290 a[1]: 0x7ffce52cf294 a[2]: 0x7ffce52cf298 int8_t是<stdint.h>定义的跨平台数

大端、小端与网络字节序

大端(Big-Endian),小端(Little-Endian)以及网络字节序的概念在编程中经常会遇到,网络字节序(Network Byte Order)一般是指大端(Big-Endian,对大部分网络传输协议而言)传输,大端小端的概念是面向多字节数据类型的存储方式定义的,小端就是低位在前(低位字节存在内存低地址,字节高低顺序和内存高低地址顺序相同),大端就是高位在前,(其中"前"是指靠近内存低地址,存储在硬盘上就是先写那个字节).概念上字节序也叫主机序. 一.大小端概念 1.首先大小

字节与小端、大端法存储。

以下仅为个人学习的记录,如有疏漏不妥之处,还请不吝赐教. 字节(byte)这个术语由 Werner Buchholz在1956年创造的.在此之前,字节通常称为syllable. 历史上,字节并非一定是8位的,但现在基本都是以8位作为1个字节.最开始字节是用来为字符编码的.C语言中的用char类型为字符编码,占1字节.可是1个字节最多只能存放256组合,也就是说,1个字节最多能表示256种字符.因此需要多个字节来表示数据.这就引出一个问题. 多字节数据怎么存储?字节的排列顺序? 在几乎所有的机器中

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

通常的技巧是使用一个指针: 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

大端模式和小端模式 网络字节顺序与主机字节顺序

在 各种计算机体系结构中,对于字节.字等的存储机制有所不同,因而引发了计算机 通信领 域中一个很重要的问题,即通信双方交流的信息单元(比特.字节.字.双字等等)应该以什么样的顺序进行传送.如果不达成一致的规则,通信双方将无法进行正 确的编/译码从而导致通信失败.目前在各种体系的计算机中通常采用的字节存储机制主要有两种:Big-Endian和Little-Endian,下面先从字节序说起.一.什么是字节序字节序,顾名思义字节的顺序,再多说两句就是大于一个字节类型的数据在内存中的存放顺序(一个字节的

主机字节序和网络字节序(大端序,小端序,网络序)

根据cpu的不同我们可以把主机字节序在内存中存储的顺序叫做主机序,也就是我们常说的,大端机和小端机.我们经常看到的有两种: 1.小端机(内存中以小端序存储的机器):将低字节序存储在开始的地址(及内存较小的内存) 2.大端机(内存中以大端序存储的机器):将高字节序存储在开始的的地址 举个例子:我们将内存从左到右排列:在内存中存放0x01020304              2000     2001    2002     2003 小 : 04             03         0

大端法、小端法、网络字节序

关于字节序(大端法.小端法)的定义 <UNXI网络编程>定义:术语“小端”和“大端”表示多字节值的哪一端(小端或大端)存储在该值的起始地址.小端存在起始地址,即是小端字节序:大端存在起始地址,即是大端字节序.

关于字节序(大端法、小端法)的定义

<UNXI网络编程>定义:术语“小端”和“大端”表示多字节值的哪一端(小端或大端)存储在该值的起始地址.小端存在起始地址,即是小端字节序:大端存在起始地址,即是大端字节序. 也可以说: 1.小端法(Little-Endian)就是低位字节排放在内存的低地址端即该值的起始地址,高位字节排放在内存的高地址端. 2.大端法(Big-Endian)就是高位字节排放在内存的低地址端即该值的起始地址,低位字节排放在内存的高地址端. 举个简单的例子,对于整形0x12345678.它在大端法和小端法的系统内中