从x86到ARM,代码移植指北

2023-05-16

最近ARM架构的处理器从云到端全面开花,比如苹果MAC上的ARM架构处理器M1 MAX就堪称王炸,华为的鲲鹏系列ARM处理器也已经稳定服务了很长时间,目前业内有口皆碑,因此基于x86环境编写的程序也都需要考虑迁移到ARM架构上去,以适应扑面而来的ARM热潮。

针对这个迁移工作笔者进行了一些预研工作。从目前的情况看基于Java、Python等高级语言开发的程序是很容易移植的,问题的关键在于不少Java的包是调用C语言代码的,这时候就要考虑 .so 的动态库移植及内联的汇编语言移植,其中要点如下。

C语言移植要点

一.解决x86下unsign char问题

-1 的二进制原码是 10000001,它的补码是除了符号外取反加 1,最后补码就是 11111111。 在 x86 架构下,char 默认是有符号的,打印时输出为-1;但是在ARM架构下 char 默认是无符号的,这个二进制的 11111111 正好就是无符号的 255。 所以,出现这种情况的原因就是 x86 架构和ARM架构对于 char 的默认处理不一样,x86默认有符号的char类型,ARM默认无符号的char类型。

对于这种情况,有两种处理方式,一种是修改源代码,把数据类型指定为有符号型,另一种就是在编译时指定参数,把默认无符号型改成默认为有符号型,即在 gcc命令后面加入-fsigned-char 编译选项,示例如下:

aarch64-redhat-linux-gcc -fsigned-char -o transfer test.c

  • 解决x86下值溢出

x86(指令集)中的浮点到整型的转换指令,定义了一个 indefinite integer value——“不确定数值”(64bit:0x8000000000000000),大多数情况下 x86 平台确实都在遵循这个原则,但是在从 double 向无符号整型转换时,又出现了不同的结果。 在这方面ARM的处理则非常清晰和简单,在上溢出或下溢出时,保留整型能表示的最大值或最小值,开发者并不会面对不确定或无法预期的结果。 double 型数据向 long 转换的结果对照如下:

CPU

double

转为long

变量保留值说明

x86

正值超出long

范围0x8000000000000000

indefinite integer value

x86

负值超出long

范围0x8000000000000000

indefinite integer value

ARM

正值超出long

范围0x7FFFFFFFFFFFFFFF

变量赋值最大的正数

ARM

负值超出long

范围0x8000000000000000

变量赋值最大的正数

因此对于C语言的double型也需要着重对于indefinite integer value做溢出检查。

汇编语言移植要点

.解决x86平台SSE、SSE2指令集的迁移问题

SSE、SSE2是x86平台上专属版权的单指令多数据流(SIMD)指令集的简称,SSE、SSE2与ARM架构的处理器上的SVE、SVE2对应。SIMD是指一条指令能处理多条数据,比如对于64位计算机来说,一条经典的指令输入、都输出只能是一个64位长的数据,针对双精度(128位长)类型的变量只能分解成若干个64位数据处理。而SIMD汇编指令可以提供由单一指令处理双精度变量的服务,其输入、输出由两个寄存器叠加组成。

目前针对x86的SSE指令向ARM的SVE汇编指令的迁移工作,已有开源项目可以实现全自动化迁移,项目下载地址:https://github.com/openestuary/sse2neon.git,使用方法如下:

步骤 1:将下载项目中的 SSE2NEON.h 文件拷贝到待移植项目中。

步骤 2 :在源文件中删除如下代码:

步骤 3: 在源代码中包含头文件 SSE2NEON.h。

解决x86平台XCHGL的迁移问题:

xchgl 是 x86 上的汇编指令,作用是交换内存变量的值,而且由于这是单指令操作,因此此操作属于原子操作。而ARM架构处理器上需要用glibc的原子操作接口__atomic_exchange_n 替换。

书籍推荐

在x86程序向ARM架构CPU的移植方面,笔者推荐《ARM嵌入式系统移植实战开发》,本书详细介绍了x86程序向ARM的移植,理论加上大量的实例,是ARM移植方面必备的工具书。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从x86到ARM,代码移植指北 的相关文章

  • GCC:如何在 MCU 上完全禁用堆使用?

    我有一个在基于 ARM Cortex M 的 MCU 上运行并用 C 和 C 编写的应用程序 我用gcc and g 编译它并希望完全禁用任何堆使用 在 MCU 启动文件中 堆大小已设置为 0 除此之外 我还想禁止代码中意外使用堆 换句话说
  • A64 Neon SIMD - 256 位比较

    我想将两个小端 256 位值与 A64 Neon 指令 asm 进行有效比较 平等 为了平等 我已经有了解决方案 bool eq256 const UInt256 lhs const UInt256 rhs bool result 首先 将
  • x86:寄存器操作为内存内容和内存地址?

    寄存器 gt 内存地址 gt 内存内容 内存地址 gt 内存内容 上面的模型正确吗 而且 如果是的话 你能建议我是否认为正确吗 movl eax ebx gt 它将 eax 的内存地址移动到 ebx 这也会导致内容移动 movl eax e
  • ARM 的内核 Oops 页面错误错误代码

    Oops 之后的错误代码给出了有关 ARM EX 中的恐慌的信息 Oops 17 1 PREEMPT SMP在这种情况下 17 给出了信息 在 x86 中它代表 bit 0 0 no page found 1 protection faul
  • 错误:-march= 开关的值错误

    我写了一个Makefile 但无法让它工作 我有一个选项应该选择编译到哪个处理器 然而 当我跑步时make从命令行它说 tandex tandex P 6860FX emulators nintendo sdks 3DS SDK HomeB
  • 原子 x86 指令与 MS 的 InterlockedCompareExchange 文档的对齐要求?

    微软提供了InterlockedCompareExchange http msdn microsoft com en us library ms683560 28VS 85 29 aspx用于执行原子比较和交换操作的函数 还有一个 Inte
  • 英特尔 JCC 勘误表 - 用于缓解的前缀有什么影响?

    Intel 推荐 https www intel com content dam support us en documents processors mitigations jump conditional code erratum pd
  • 将 C 函数与 ARM 汇编结合使用

    我见过人们在代码中使用 C 库中的 printf 的示例 如下所示 data balign 4 hello asciz Hello n text global main func main main ldr r0 hello msg bl
  • 如何在 Linux 中制作一个将文件转换为大写的 x86 汇编程序?

    我找到了一个名为 ProgrammingGroundUp 1 0 booksize pdf 的 pdf 文件 其中一个项目是制作一个汇编程序 该程序接收文件并将其转换为大写 section data CONSTANTS system cal
  • 如何找出英特尔处理器上的指令触及了哪条高速缓存线?

    我读了这篇文章关于 Meltdown Spectre 漏洞利用 http www theregister co uk 2018 01 04 intel amd arm cpu vulnerability 允许利用 CPU 中的硬件错误从内核
  • 如何在 x86 汇编中编写自修改代码

    我正在考虑为我最近开发的一个业余爱好虚拟机编写一个 JIT 编译器 我了解一些汇编语言 我主要是一名 C 程序员 我可以阅读大多数汇编语言并参考我不理解的操作码 并编写一些简单的程序 但是我很难理解这几个示例我在网上找到的自我修改代码 这是
  • 给寄存器赋值并加减

    我对此完全迷失了 我需要使用寄存器来计算以下表达式的编程 varA varA varB varC varD 其中 varA varB 等是变量 将整数值分配给上述变量的 EAX EBX ECX 和 EDX 寄存器 这意味着 您可以对输入进行
  • 让 GCC/Clang 使用 CMOV

    我有一个简单的标记值联合 这些值可以是int64 ts or doubles 我正在对这些联合进行加法 但需要注意的是 如果两个参数都代表int64 t值 那么结果也应该有一个int64 t value 这是代码 include
  • 为什么我可以访问寄存器中较低的双字/字/字节,但不能访问较高的双字/字/字节?

    我开始学习汇编程序 这对我来说看起来不合逻辑 为什么我不能在寄存器中使用多个高字节 我明白了历史原因rax gt eax gt ax 所以让我们关注new64 位寄存器 例如 我可以使用r8 and r8d 但为什么不呢r8dl and r
  • 返回地址预测堆栈缓冲区与堆栈存储的返回地址?

    一直在阅读 Agner Fog 的 Intel AMD 和 VIA CPU 的微架构 他在第 34 页描述了 返回地址预测 http www agner org optimize microarchitecture pdf http www
  • ARM、VFP、浮点、惰性上下文切换

    我正在为 ARM 处理器 Cortex A9 编写操作系统 我正在尝试实现浮点寄存器的延迟上下文切换 这背后的想法是 浮点扩展最初对线程禁用 因此不需要在任务切换上保存浮点上下文 当线程尝试使用浮点指令时 会触发异常 然后 操作系统启用浮点
  • 是否可以调用驻留在 exe 中的非导出函数?

    我想调用驻留在第 3 方 exe 中的函数并获取其结果 好像有should是一种方法 只要我知道函数地址 调用约定等 但我不知道如何 有谁知道我会怎么做 我意识到任何解决方案都是非标准的黑客 但有must成为一种方式 我的非恶意用例 我正在
  • 什么是 .axf 文件?

    我是arm架构的新手 我从事嵌入式软件工作 并试图了解我的项目二进制文件的调试文件夹中存在的 axf文件 发现它是链接器在构建过程中生成的arm可执行格式文件 用于调试崩溃 所以很明显它包含了一些调试信息 但不清楚具体是什么信息 而且deb
  • 函数地址不是实际代码地址

    在 Visual Studio 2008 C 中调试一些代码时 我注意到函数指针变量中的地址不是函数本身的实际地址 这是一个外部 C 函数 int main void printaddr const char print debug sho
  • Intel 上的 gcc 中的 _mm_pause 用法

    我参考过这个网页 https software intel com en us articles benefitting power and performance sleep loops https software intel com

随机推荐

  • 新手小白,求教matlab

    用matlab写了个求阶乘的函数 xff0c function y 61 digui n n为元素个数 if n lt 61 1 y 61 1 end y 61 digui n 1 n end 结果显示 xff1a 内存不足 可能的原因是程
  • 字符串有长度限制吗?是多少?

    首先字符串的内容是由一个字符数组 char 来存储的 xff0c 由于数组的长度及索引是整数 xff0c 且String类中返回字符串长度的方法length 的返回值也是int xff0c 所以通过查看java源码中的类Integer我们可
  • C++实现推理, 基于Onnx-simplifier、onnx-tensorrt、TensorRT和Cuda编程

    Cuda基础 深度学习模型推理 为啥需要学习tensorRT 因为需要加速 需要C 43 43 部署 为啥又需要学习cuda编程呢 因为有些前处理 后处理需要cuda编程来并行运算进行加速 比如anchor的解码 nms等后处理 1 CUD
  • nuScenes、Culane数据集、Camera选型及内参标定、TX2外接双目相机ZED

    1 xff1a nuScenes数据集 https zhuanlan zhihu com p 295549692 nuScenes mini data 点云数据集 针对cuda10 0 spconv版本 安装cu100版本 torch 1
  • 指针指向0的问题

    问 xff1a 定义指针变量int a 61 0 是指针变量指向地址为零的数据吗 xff1f 答 xff1a 指针赋0 xff0c 就是不指向任何对象 xff0c 相当于NULL
  • pip install basicsr安装时在Preparing metadata (setup.py)卡住

    pip install basicsr安装时在Preparing metadata setup py 卡住 如下图pip安装basicsr时卡在Preparing metadata 查了很多资料也没解决 xff0c 最后从pypi下载包通过
  • Ros 图(节点,消息,话题)命令

    1 启动守护进程 xff1a roscore xff1a ros 43 core这条命令会启动ros的核心模块 xff0c 我感觉这个是一个守护进程 xff0c 会在11311端口 xff08 可能会有不同的配置 xff09 启动一个soc
  • Android 串口通信(二)

    前言 上一篇中主要介绍了串口基础内容和基于谷歌官方android serialport api库 对Android设备进行的串口操作 xff0c 这篇文章主要介绍基于Usb转串口驱动库usb serial for android 的相关内容
  • DeepMind带来了大魔王阿尔法扣,程序员还有前途吗?

    最近 著名的编程竞赛网站C odeforces 发布了一篇名为 AlphaCode DeepMind Solves Programming Problems on CodeForce 的文章 xff0c 将阿尔法扣 xff08 AlphaC
  • 最优控制理论 四、线性二次型最优控制和LQR

    在前面两节最优控制理论 二 哈密尔顿函数法 xff0c 我们利用Hamilton函数法讨论了终端等式约束的非线性控制系统的最优控制 xff0c 它所解决的是 x
  • 多源传感器GNSS INS 视觉 LiDAR 组合导航与SLAM开源项目总结

    多源传感器GNSS INS 视觉 LiDAR 组合导航与SLAM开源项目总结 本文基于 吴桐wutong 微信公众号文章完善而来 开源代码总览 名称传感器类型组合类型滤波方法备注RTKLIBG KFGAMP rtklibexplorer h
  • Integer类超详解

    目录 xff08 点击传送 x1f680 x1f680 xff09 前言 Integer的内部结构 1 MAX VALUE 2 MIN VALUE 3 SIZE 4 TYPE 构造方法 1 Integer xff08 int number
  • PPM信号介绍

    原文地址 xff1a http nicekwell net blog 20161223 ppmxin hao jie shao html 我们知道PWM信号可以控制舵机 xff0c 一般信号周期是20ms xff0c 脉宽在500us 25
  • 算法建模语言比较:C的优势(相比于Matlab)

    数据结构定义 structure 方便组织相关数据 union 方便多角度访问数据 xff08 软件角度 硬件角度等 xff09 bit field 方便硬件角度访问数据 内存分配方式 malloc 预先 灵活申请内存空间 xff0c 拓展
  • 学会使用CMakeLists.txt在VScode中搭建C++工程

    目录 一 Cmake 简介 二 常用命令 1 指定 cmake 的最小版本 2 设置项目名称 3 设置变量 3 1 set 直接设置变量的值 3 2 set 追加设置变量的值 3 3 list 追加或者删除变量的值 4 添加第三方库或链接其
  • WIN10源码编译安装QGC-V3.4

    目录 写在前面 环境 安装VS2015 xff08 采用的是社区版 xff09 安装Git xff08 见GIT安装教程 xff09 并克隆QGC源码 安装Qt xff0c 并用Qt进行编译 运行 安装注意事项 写在前面 最近想起来之前有过
  • 飞控固件烧录方法

    目录 写在前面 方法一 方法二 写在前面 整理两个烧录飞控固件的方法 方法一 1 xff09 waf targets bin ardusub upload 这时两个过程 xff0c 第一个过程target 会产生一个 px4 文件 xff0
  • Ubuntu 20.04 LTS 安装qt4 library

    How to Install Qt4 Libraries in Ubuntu 20 04 LTS July 9 2020 3 Comments The Qt4 framework has been removed from Ubuntu 2
  • STM32接入ONENET-实现数据上传和命令下发

    前言 xff1a 使用ONENET平台进行远程传输数据和远程控制开发板是相对简单的事 xff0c 但由于ONENET官方给的代码只对他家的开发板比较友好 xff0c 对于初学者来说修改这些代码相对麻烦 xff0c 所以我就分享一份STM32
  • 从x86到ARM,代码移植指北

    最近ARM架构的处理器从云到端全面开花 xff0c 比如苹果MAC上的ARM架构处理器M1 MAX就堪称王炸 xff0c 华为的鲲鹏系列ARM处理器也已经稳定服务了很长时间 xff0c 目前业内有口皆碑 xff0c 因此基于x86环境编写的