C++ GCC生成了一个未对齐的“;ldrd“;指示

C++ GCC生成了一个未对齐的“;ldrd“;指示,c++,gcc,arm,C++,Gcc,Arm,使用以下gcc标志 arm-none-eabi-g++ -MMD -MP -MF /c/Users/Joshua/Documents/desmume-0.9.11-win64/SM64DSe/SM64DSe/ASMPatchTemplate/build/PeachToadAbilities.d -g -Wall -O2 -march=armv5te -mtune=arm946e-s -fomit-frame-pointer -ffast-math -iquote /c/Users/Joshua

使用以下gcc标志

arm-none-eabi-g++ -MMD -MP -MF /c/Users/Joshua/Documents/desmume-0.9.11-win64/SM64DSe/SM64DSe/ASMPatchTemplate/build/PeachToadAbilities.d -g -Wall -O2 -march=armv5te -mtune=arm946e-s -fomit-frame-pointer -ffast-math  -iquote /c/Users/Joshua/Documents/desmume-0.9.11-win64/SM64DSe/SM64DSe/ASMPatchTemplate/include -I/c/devkitPro/libnds/include -I/c/devkitPro/devkitARM/include -I/c/devkitPro/devkitARM/arm-none-eabi/include -I/c/Users/Joshua/Documents/desmume-0.9.11-win64/SM64DSe/SM64DSe/ASMPatchTemplate/build -DARM9 -nodefaultlibs -I. -fno-builtin -c --std=c++14 -fno-rtti -fno-exceptions -Wa,-adl=PeachToadAbilities.lst -c /c/Users/Joshua/Documents/desmume-0.9.11-win64/SM64DSe/SM64DSe/ASMPatchTemplate/source/C_PeachToadAbilities/PeachToadAbilities.cpp -o PeachToadAbilities.o
(请特别注意,体系结构为ARMv5TE,CPU为ARM946E-S) 为最后一个函数生成以下ASM:

push    {r4, lr}
mov     r4, r0
mov     r1, #0x0
ldrd    r2, [r4, #0x5c]
ldr     ip, [r0, #0x98]
ldr     r0, [r0, #0x280]
lsl     ip, ip, #0x1
str     ip, [r4, #0x98]
ldr     ip, [r4, #0x64]
sub     sp, sp, #0x10
strb    r1, [r4, #0x27d]
add     r3, r3, #0x48000
str     r1, [sp, #0x8]
str     r1, [sp, #0x4]
str     ip, [sp]
mov     r1, #0x4a
bl      _ZN8Particle6System3NewEjj5Fix12IiES2_S2_PK11Vector3_16fPNS_8CallbackE
str     r0, [r4, #0x280]
add     sp, sp, #0x10
pop     {r4, pc}
在上下文中,这是一个任天堂DS游戏的ROM破解。播放机结构是4字节对齐的,偏移量0x5C处是播放机的位置,它是3个Fix12的结构(Fix12是1个4字节整数的结构)


问题在于,gcc生成的“ldrd”指令无法证明能够访问8字节对齐的地址(它不应该知道“player”在哪里,而且0x5C不是8的倍数)。我看过的ARM文档表明,对于ARMv5,加载未对齐的双字是未定义的行为。但是,没有$gba和DeSmuME假设当地址为4字节对齐时,这样的访问仍然从该地址加载8字节的值。ARM946E-S CPU上的ARMv5TE的这种行为正确吗?(我没有在实际的DS上测试这一点,因为我没有闪存卡。)

很可能类实例与某些字节对齐(例如64个字节),并且头不是8个字节的倍数,因此成员变量打包在从“未对齐”地址开始的位置,以便与“未对齐”地址组合偏移量,如0x5c,地址保证8字节对齐

编译器并不完美,但我无法想象他们会犯这样的小错误


所以别担心。

我也看到了ARMv5TE、ARM946E-S和GCC 6的这一点(在5中还可以)。在我的例子中,代码加载了一个数组的两个连续元素,但编译器无法证明传入的数组指针是8字节对齐的。我将尝试生成一个简单的示例并报告这一点。您也应该这样做,希望它能得到修复。

看起来8字节对齐要求已经从以后的Arm体系结构中删除,而GCC并没有遵守旧的要求。一种可能的解决方法是禁用这些指令,只为ARMv5T编译?显示
播放器的定义。(最好张贴