This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Simple ARM code generation
- From: Steve Freeland <caucasatron at yahoo dot ca>
- To: gcc-help at gcc dot gnu dot org
- Date: Mon, 14 Aug 2006 15:15:46 -0700 (PDT)
- Subject: Simple ARM code generation
- Reply-to: Steve Freeland <caucasatron at yahoo dot ca>
Hello,
I'm attempting to use gcc (the WinARM build, see -v output below) to compile the following stub program:
int AEEMod_Load(IShell *pIShell, void *ph, IModule **ppMod)
{
return ENOMEMORY; /* defined to "2" */
}
The output disassembles to the following:
Disassembly of section .text:
00000000 <AEEMod_Load>:
0: e1a0c00d mov ip, sp
4: e92dd800 stmdb sp!, {fp, ip, lr, pc}
8: e24cb004 sub fp, ip, #4 ; 0x4
c: e24dd00c sub sp, sp, #12 ; 0xc
10: e50b0010 str r0, [fp, #-16]
14: e50b1014 str r1, [fp, #-20]
18: e50b2018 str r2, [fp, #-24]
1c: e3a03002 mov r3, #2 ; 0x2
20: e1a00003 mov r0, r3
24: e24bd00c sub sp, fp, #12 ; 0xc
28: e89da800 ldmia sp, {fp, sp, pc}
This code crashes the device I'm working with.
There seems to be a problem with the use of stmdb and ldmia to save and restore the register context to the stack. The stmdb instruction saves 4 registers, and the ldmia only restores 3 of them, one of which (sp) isn't in the original 4. This trick seems to be common, but I don't understand how it works. What order are the registers saved and loaded in? As far as I can tell, at the end the pc register ends up with either the original fp or sp.
What needs to happen is for the original sp to be restored, and the original lr to be loaded into pc (the "return").
If I change the two last lines to the following:
24: e24bd004 sub sp, fp, #4 ; 0x4
28: e12fff1e bx lr
The code works correctly. Can anyone explain this to me?
Thanks in advance,
- Steve
gcc -v output:
$ c:/Progra~1/winarm/bin/arm-elf-gcc -v
Using built-in specs.
Target: arm-elf
Configured with: ../../gcc-4.1.1/configure --enable-languages=c,c++ --enable-interwork --enable-multilib --with-gcc --with-gnu-ld --with-gnu-as --with-stabs --disable-shared --disable-threads --disable-libssp --disable-libstdcxx-pch --disable-libmudflap --disable-win32-registry --disable-nls --disable-debug --without-headers --with-newlib --target=arm-elf --prefix=c:/WinARM -v
Thread model: single
gcc version 4.1.1 (WinARM)