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

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

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

   最近,该公司希望改变核心处理器,由小端处理器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的数据,处理器怎样获取的问题。


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

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

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/117418.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • TDSCDMA SIB content[通俗易懂]

    TDSCDMA SIB content[通俗易懂]SIB1:包括NAS系统信息,UE在空闲态和连接态下所使用的定时器和常数信息。 SIB2:URAID信息。 SIB3:小区选择和重选的参数,包括Cellidentity、Cellselectionandre-selectioninfo和CellAccessRestriction三个信息IE。下面对这些IE的内容进行深入剖析。   

  • 贴片电阻电容参数_贴片电阻的规格

    贴片电阻电容参数_贴片电阻的规格贴片电阻九大尺寸规格识别表英制封装体积 公制封装体积 长(L)(mm) 宽(W)(mm) 高(t)(mm) a(mm) b(mm) 0201 0603 0.60±0.05 0.30±0.05 0.23±0.05 0.10±0.05 0.15±0.05 0402 1005 1.00±0.10 0.50±0.10 0.30±0.10 0.20±0.10 0.25±0.10 0603 .

  • Spring boot Mybatis 整合(注解版)

    Spring boot Mybatis 整合(注解版)之前写过一篇关于springboot与mybatis整合的博文,使用了一段时间spring-data-jpa,发现那种方式真的是太爽了,mybatis的xml的映射配置总觉得有点麻烦。接口定义和映射离散在不同的文件中,阅读起来不是很方便。于是,准备使用mybatis的注解方式实现映射。如果喜欢xml方式的可以看我之前的博文:SpringbootMybatis整合(完整版)开发环境:开

  • android 参数 attrs.xml,android – 定义自定义attrs

    android 参数 attrs.xml,android – 定义自定义attrs传统的方法充满了样板代码和笨拙的资源处理。这就是我制作Spyglass框架的原因。为了演示它是如何工作的,这里有一个示例,展示如何创建一个显示字符串标题的自定义视图。第1步:创建自定义视图类。publicclassCustomViewextendsFrameLayout{privateTextViewtitleView;publicCustomView(Contextcont…

  • nginx正向代理(超简单)

    正向代理是一个位于客户端和原始服务器之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。环境192.168.153.179:正向代理192.168.153.178:客户端CentOSLinuxrelease7.5.1804(Core)关闭防火墙和selinux开始部署:首先,两台服务器安装nginx源码安装:1、安装启动安装依赖yum-yinstallwgetgcc

  • JVM内存分配与管理详解

    JVM内存分配与管理详解概述了解C++的程序员都知道,在内存管理领域,都是由程序员维护与管理,程序员用于最高的管理权限,但对于java程序员来说,在内存管理领域,程序员不必去关心内存的分配以及回收,在jvm自动内存管理机制的帮助下,不需要想C++一样为每一个new操作去编写delete/free代码,这一切交给jvm,但正是这一切都交给了jvm,一旦出现内存泄漏与溢出,如果不了jvm,那么对于程序的编写与调试将会非常

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号