gpt4 book ai didi

c++ - GCC 生成了未对齐的 "ldrd"指令

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:08:03 25 4
gpt4 key购买 nike

编译此 C++ 代码时:

#include "../SM64DS_2.h"

//@021026a0, hooks: 0x020bddb8, 0x020bde0c
void CancelPowerups(Player& player)
{
if(player.isFreezeFramePeach)
{
player.isFreezeFramePeach = false;
player.EndMusic(0x33);
}
if(player.isDashyToad)
{
player.isDashyToad = false;
player.EndMusic(0x33);
}
}

//hook: 0x020b98f8
void EnableFreezeFramePeach(Player& player)
{
//TODO: Show message on first use
player.isFreezeFramePeach = true;
player.flowerPowerTimer = 600;
player.SetMusic(0x33);
}

//hook: 0x020b9904
void EnableDashyToad(Player& player)
{
//TODO: Show message on first use
player.isDashyToad = true;
player.flowerPowerTimer = 600;
player.SetMusic(0x33);
}

//hook: 0x020e4f10
void WorkDashyToadPart1(Player& player)
{
//TODO: Deal with speed of walking animation
if(player.isDashyToad)
{
player.horzSpeed /= 2;
player.isSpeedHalfed = true;
if(player.walkOnWaterTimer == 61)
++player.walkOnWaterTimer;
}
}

//hook: 0x020e52e8
void WorkDashyToadPart2(Player& player)
{
if(player.isSpeedHalfed)
{
player.horzSpeed *= 2;
player.isSpeedHalfed = false;
player.dashyToadParticleSysID = Particle::System::New(player.dashyToadParticleSysID,
0x4a,
player.pos.x,
player.pos.y + Fix12i(72),
player.pos.z,
nullptr,
nullptr);
}
}

使用以下 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}

就上下文而言,这是 Nintendo DS 游戏的 ROM hack 片段。 Player结构体是4字节对齐的,偏移量0x5C处是玩家的位置,是一个3个Fix12 的结构体(一个Fix12 是一个4字节整数的结构体)。

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

最佳答案

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

关于c++ - GCC 生成了未对齐的 "ldrd"指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46576362/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com