android-ndk - Android 原生代码在拇指模式下崩溃,但在 ARM 模式下不崩溃

标签 android-ndk arm

我正在尝试使用 android NDK 编译和运行 android 平台的 native 代码。 在代码中的许多地方,我尝试将短整数指针转换为整数指针,因此它存在内存对齐问题,尽管它在 X86 上正常工作。我正在拇指模式下编译代码,由于如上所述的未对齐访问,代码很糟糕。但如果我在 ARM 模式下编译代码,它不会崩溃并且可以正常工作。

我的疑问是为什么代码在arm模式编译中没有崩溃,尽管它有内存对齐问题。

我对 ARM 和 THUMB 指令集知之甚少。我知道ARM指令集是32位宽,而thumb指令集是16位宽。但它对于未对齐访问有何影响?

最佳答案

我认为崩溃不是由指令编码长度引起的。 ARM 和 Thumb 模式应该具有相同的能力从对齐或未对齐的地址加载数据

首先,您是否使用真正不允许未对齐 32 位加载的 ARMv5 硬件?因为较新的 ARM 芯片,例如运行针对 ARMv5TE 编译的 Android 的 ARMv6 ( ARM11 ) 芯片,可以执行未对齐的 32 位加载并且不会崩溃。当然,如果您的 list 声明它是为 ARMv5TE 编译的,那么在真正的 ARMv5 硬件上运行的 Android 设备会很高兴地安装它并崩溃 - 您有责任确保您的应用与其声明的内容真正兼容。

Qemu(包括 Android SDK 中捆绑的模拟器)在模拟 arm926ej-s无法正确模拟未对齐 32 位加载时的崩溃。 (ARMv5TEJ) 芯片。你不能依赖模拟器来捕捉这个。在这方面,它确实只对 Java 开发有利。

你能看到 gdb 中的崩溃吗?您可以显示寄存器转储并查看来自未对齐地址的负载吗?您确定编译器不会(以允许的方式)更改代码的含义吗?

对于 x86 之外的可移植性,您确实不应该执行从 uint16_t*uint32_t* 的转换。 C 语言不保证它们能够工作。从技术上讲,您的代码始终是“错误的”。看看野外的可移植代码:它使用预处理器宏或静态内联函数来抽象出“get_unaligned_le32”等概念或 x86 上依赖于未对齐访问的整个函数。

关于android-ndk - Android 原生代码在拇指模式下崩溃,但在 ARM 模式下不崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9975925/

相关文章:

android - 我无法将我的项目与 gradle 同步?

android - OSMdroid mapview 的两指旋转

android - Android 上的 OpenSL ES 替代方案

assembly - ARM 拇指中的表分支字节(TBB)的简单示例

Android Webview 响应读取

android eclipse jedisct1/libsodium 从哪里开始

ios - ranlib 缺少在 iOS 上编译 GNU bash

debugging - 为什么 64 位 gdb 在 ARM 32 代码中永远不会到达断点?

c - 在 core_cm4.h 上,为什么会有类似 ((uint32_t)(int32_t)IRQn) 的转换?

c - 使用 ARM Cortex SysTick 计算运行时间;当 SysTick 计数器翻转时会发生什么?