Jay*_*rod 30 c architecture arm isa
我对ARM编程很新.我注意到有几种架构,如ARMv4,ARMv5,ARMv6等.这些架构有什么区别?他们有不同的指令集或行为吗?
最重要的是,如果我为ARMv6编译一些C代码,它会在ARMv5上运行吗?在ARMv6上运行的ARMv5代码怎么样?或者,如果我编写内核汇编代码,我只需要担心区别吗?
Tho*_*nin 35
ARM世界有点凌乱.
对于C程序员来说,事情很简单:所有ARM架构都提供常规的32位平面寻址编程模型.只要您使用C源代码,您可能会看到的唯一区别是有关字节序和性能的信息.大多数ARM处理器(甚至旧型号)都可以是big-endian和little-endian; 然后由逻辑板和操作系统做出选择.好的C代码是endian中立的:无论平台字节顺序如何,它都可以编译和正常工作(字节序中立性有利于可靠性和可维护性,但也有利于性能:非中性代码是通过不同大小的指针访问相同数据的代码,这会严重破坏编译器用来优化代码的严格别名规则.
如果考虑二进制兼容性(即重用已编译一次的代码),情况就完全不同了:
给定处理器可以实现多个指令集.只知道ARM代码的最新处理器是StrongARM,这是一个已经相当陈旧(15年)的ARMv4代表.ARM7TDMI(ARMv4T架构)同时了解ARM和Thumb,几乎所有后续ARM系统(Cortex-M除外)都是如此.ARM和Thumb代码可以在同一个应用程序中混合在一起,只要在约定发生变化时插入适当的粘合剂; 这称为拇指互通,可以由C编译器自动处理.
Cortex-M0只知道Thumb指令.它知道一些扩展,因为在"普通"ARM处理器中,操作系统必须使用ARM代码(用于处理中断); 因此,Cortex-M0知道几个Thumb-for-OS的东西.这与应用程序代码无关.
另一个Cortex-M只知道Thumb-2.Thumb-2 主要向后兼容Thumb,至少在汇编级别.
因此,如果使用编译器开关编译某些代码,告知这是针对ARMv6的,那么编译器可能会使用ARMv6中的少数指令而不是ARMv5.这是几乎所有平台上遇到的常见情况:例如,如果您使用GCC在PC上编译C代码-march=core2
,那么生成的二进制文件可能无法在较旧的奔腾处理器上运行.
调用约定是一组规则,它们指定函数如何交换参数和返回值.处理器只知道它的寄存器,并且没有堆栈的概念.调用约定告诉参数进入哪些寄存器,以及它们是如何编码的(例如,如果有一个char
参数,它进入寄存器的低8位,但是调用者应该清除/符号扩展高24位,或不 ?).它描述了堆栈结构和对齐.它规范了对齐条件和结构字段的填充.
ARM有两种主要约定,称为ATPCS(旧)和AAPCS(新).它们在浮点值方面有很大不同.对于整数参数,它们大多数相同(但AAPCS需要更严格的堆栈对齐).当然,约定取决于指令集和Thumb交互的存在.
在某些情况下,可能有一些符合ATPCS和AAPCS的二进制代码,但这是不可靠的,并且没有不匹配的警告.因此,底线是:您不能在使用不同调用约定的系统之间实现真正的二进制兼容性.
ARM体系结构可以使用可选元素进行扩展,这些元素将自己的指令添加到核心指令集.FPU是一个可选的协处理器(在实践中很少遇到).另一个协处理器是NEON,这是一些较新的ARM处理器上的SIMD指令集.
使用协处理器的代码不会在不具有协处理器功能的处理器上运行,除非操作系统捕获相应的操作码并在软件中模拟协处理器(这或多或少是使用ATPCS调用时浮点参数发生的情况)惯例,它很慢).
总而言之,如果你有C代码,那么重新编译它.不要尝试重用为其他体系结构或系统编译的代码.
想想这个ARM与ARM之类的东西,比如wintel计算机和intel mac.假设你在两台计算机上都拥有相同的intel芯片(系列),那么你的C代码的一部分可以编译一次并在两个处理器上运行就好了.您的程序变化的位置和原因与英特尔处理器无关,但与其周围的芯片和主板以及本案例中的操作系统有关.
对于ARM与ARM,大多数差异不是核心,而是围绕核心的供应商特定逻辑.所以这是一个加载的问题,如果你的C代码是一些应用程序调用标准的api调用,那么它应该在arm或intel或powerpc或其他任何东西上编译.如果您的应用程序与片上或板载外设进行通信,那么无论处理器类型是什么,一块板,一块芯片都会有所不同,因此必须为该芯片或主板编写C代码.如果为ARMv6编译二进制文件,它可以并且将在ARMv4上具有未定义的指令,并将导致异常.如果为ARMv4编译,ARMv6应该运行它就好了.
充其量,如果您在此应用程序空间中,那么您可能会看到的只是性能差异.其中一些与您在编译器选项中的选择有关.有时你可以帮助你的代码.我建议尽可能避免分裂和浮点.我不喜欢乘法,但如果推动,将采取乘法而不是除数.x86已经让我们破坏了未对齐的访问,如果你现在开始使用对齐的I/O,当你进入其他更喜欢对齐访问的芯片时,它会为你节省时间,或者你会得到各种各样的操作系统和bootloaders配置ARM进行响应,这些都不是你在x86上习惯的.同样保持这种习惯,你的x86代码运行得更快.
获取ARM ARM的副本(谷歌:ARM架构参考手册,你可以免费下载很多地方,我不知道当前的转速是什么,转换我或者其他什么).浏览ARM指令集,看到所有内核都支持大多数指令,有些指针随时间增加,如divide和byteswap等.你会发现内核之间没有什么可担心的.
从系统角度思考,wintel与intel mac.ARM不制造芯片,制造和许可核心.在他们的芯片中使用ARM的大多数供应商都有自己的特殊酱.所以它就像wintel与mac在中间使用相同的处理器,但在涉及处理器接触和必须使用的所有东西时完全不同.它并不止于ARM内核,ARM销售外围设备,浮点单元,缓存等.例如,如果有任何ARMv4是相同的那么少.如果您的代码触及差异,那么如果您不知道,那么您将遇到问题.
除了ARM ARM之外,对于芯片的臂部分,还有TRM(技术参考手册).但如果你使用它的组件得到错误的trm可能会让你头疼.TRM可能有寄存器描述和ARM ARM没有的其他东西,但是如果你住在应用程序空间中,你可能不需要它们,也不需要ARM ARM.如果没有别的,ARM ARM很适合教育目的.了解为什么您可能不想划分或使用未对齐的访问.