Android ndk Android本机代码在thumb模式下崩溃,但在arm模式下不崩溃

Android ndk Android本机代码在thumb模式下崩溃,但在arm模式下不崩溃,android-ndk,arm,Android Ndk,Arm,我正在尝试使用android NDK为android平台编译和运行本机代码。 在代码中的许多地方,我试图将一个短整数指针转换为整数指针,因此它存在内存对齐问题,尽管它在X86中工作正常。我是在thumb模式下编译代码的,正如我前面所说的,由于未对齐的访问,代码被破坏了。但是如果我在ARM模式下编译代码,它就不会崩溃,也不能正常工作 我的疑问是为什么代码在arm模式编译中没有崩溃,尽管它有内存对齐问题 我对ARM和THUMB指令集知之甚少。我知道手臂指令集是32位宽,拇指是16位宽。但是它对未对齐

我正在尝试使用android NDK为android平台编译和运行本机代码。 在代码中的许多地方,我试图将一个短整数指针转换为整数指针,因此它存在内存对齐问题,尽管它在X86中工作正常。我是在thumb模式下编译代码的,正如我前面所说的,由于未对齐的访问,代码被破坏了。但是如果我在ARM模式下编译代码,它就不会崩溃,也不能正常工作

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


我对ARM和THUMB指令集知之甚少。我知道手臂指令集是32位宽,拇指是16位宽。但是它对未对齐的访问有什么影响呢?

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

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

Qemu(包括Android SDK中捆绑的仿真器)在模拟(ARMv5TEJ)芯片时,无法正确模拟未对齐的32位负载上的崩溃。你不能依靠模拟器来捕捉这一点。在这方面,它只对Java开发有好处

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


对于x86之外的可移植性,您实际上不应该执行从
uint16\u t*
uint32\u t*
的强制转换。C语言不能保证它们能正常工作。从技术上讲,您的代码总是“错误的”。看看野外的可移植代码:它使用预处理器宏或静态内联函数来抽象出诸如“get_unaligned_le32”之类的概念或x86上依赖于未对齐访问的整个函数。

Thumb指令的长度为16位,而ARM指令的大小为32位

这意味着在ARM模式下,可以保证代码中的数据部分是4字节对齐的,但不是在Thumb模式下

您可以尝试对齐指令。对齐语法因编译器/汇编程序而异

某些库中的某些(硬件相关)例程假定数据是4字节对齐的,而与数据类型无关。 如果不满足此条件,则会导致崩溃或性能严重受损


此外,如果考虑到缓存,最好还是对齐性能关键型数据。缓存友好的对齐方式因SoC而异,但在ARM11上通常为32字节,在Coretex上通常为64字节。

非常感谢您的回复,我还怀疑崩溃是否总是定义错误内存访问的结果,或者它可能不会崩溃?因为在我的代码中有许多指针错误地对齐了地址,但是代码崩溃时只有几个指针,而不是所有指针,所以请让我知道你对此的评论。在thumb模式下,有50%的几率数据是4字节对齐的。这就解释了这种不一致性。