2017-10-05 160 views
1

當編譯該C++代碼:GCC產生的未對齊 「LDRD」 指令

#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} 

對於康特xt,這是一款任天堂DS遊戲的ROM破解版。播放器結構是4字節對齊的,並且在偏移0x5C處是播放器的位置,這是3的結構。Fix12 <int>(A Fix12 <int>是1個4字節整數的結構)。

問題是gcc生成一個不能被證明訪問8字節對齊地址的「ldrd」指令(它不應該知道「player」在哪,除此之外,0x5C不是8的倍數) 。我看過的ARM文檔說,對於ARMv5,加載未對齊的雙字是未定義的行爲。但是,沒有$ gba和DeSmuME假設地址是4字節對齊時的這種訪問仍然從該地址加載一個8字節的值。對於ARM946E-S CPU上的ARMv5TE,這是正確的行爲嗎? (我沒有在實際的DS上測試過,因爲我沒有閃存卡。)

+0

看起來像是從後來的Arm體系結構中刪除了8字節的對齊要求,而GCC沒有遵守舊的要求。可能的解決方法可能是僅通過編譯ARMv5T來禁用這些指令? – NickJH

回答

0

大多數情況下,類實例與特定字節(例如64字節)對齊,而且標題不是因此成員變量被封裝在一個以「未對齊」地址開始的位置,所以與0x5c這樣的「未對齊」偏移量結合起來,地址保證8個字節對齊。

編譯器並不完美,但我無法想象他們會犯這麼小的錯誤。

所以不要擔心。