Newbie: arm-elf-gcc generated asm question

Hi,

I have started evaluating the GNUARM tools for a LPC210x target (little-endian) and come across the following which is odd to me.

With ul defined as: unsigned long *ul;

The function function1 returns a pointer to void. For the following line, ul = ( unsigned long * ) function1();

GCC uses R0 to return the function1() result which is 0x40000625, the instruction: STR R0, [R4,#0x0004]

stores the result to RAM. Inspecting the RAM location [R4, #0x0004] shows the value stored correctly in little endian form as 25 06 00 40.

So far so good...

Now I have another function that takes ul as an argument. GCC uses R0 to pass the argument to the function. The code generated to load R0 is: LDR R0, [R2,#0004] where R2 in this case has the same value as R4 in the previous case - but the value loaded into R0 is 0x25400006 - which is all the correct digits but in the wrong order!

I am using a simulator to run the code - both Insight and the Keil simulators behave exactly the same, so I am assuming I have done something stupid in the setup of the mpu.

Any ideas what???

Thanks.

Reply to
Ken Barlow
Loading thread data ...

Check that R2 is word aligned. If it is not, the loaded value will be rotated.

Your address seems to have bit 0 set. If this is the case -- the compiler is doing something really nasty.

HTH, Vadim

Reply to
Vadim Borshchev

but

Thanks for the advice - the variable being assigned is actually part of a structure (I simplified the example). Ensuring the variable started on a

4byte boundary fixed the problem. Pointer alignment troubles!

Is there a way of forcing all alignment onto four byte boundaries? I've looked through the GCC and LD docs and can find switches for other targets, but not the ARM.

Thanks again!

Reply to
Ken Barlow

Compiler does this automatically. If you, say, have the structure

struct { uint8_t one; uint32_t two; } foo;

then foo.two will always be word aligned.

What are your trying to do? If you would post a snippet of your data structure it might be easier to help.

Vadim

Reply to
Vadim Borshchev

Are you using the compiler switch '-fpack-struct' ? If so you must manually ensure the correct padding is used.

Andy

Reply to
Andy Sinclair

The compiler will properly align all variables and structure fields unless you tell it to do otherwise.

IOW, you had to write code that does something bad to get such an alignment problem (most likely typecasting a pointer or using a packed struct). You're probably better off not doing "bad" things rather than forcing the alignment of everything to a word boundary. If you explain what it is you're actually trying to do, somebody can show you how to do it the "good" way.

--
Grant Edwards                   grante             Yow!  ... I'm IMAGINING a
                                  at               sensuous GIRAFFE, CAVORTING
                               visi.com            in the BACK ROOMof a KOSHER
                                                   DELI --
Reply to
Grant Edwards

Hi again,

The structure is like this:

struct { uint8 aByte; uint8 aByteArray[ 64 ]; } foo;

Hence my problem - the aByteArray is used as a generic buffer that can hold anything. I was putting 32bit words into it, and as a byte array there is no way of the compiler knowing that I wanted it 32bit aligned - a bit silly now I come to look at it but sometimes it takes somebody else to point out you are doing something daft ;-)

In answer to the other question: I'm not using -fpack-struct.

Thanks again.

Reply to
Ken Barlow

You probably need to use memcpy() to copy data to/from your buffer. You could force alignment of the beginning of the array, but things will still fall apart if you use type-punned pointers to put multiple things of differing sizes into the buffer.

--
Grant Edwards                   grante             Yow!  Nice decor!
                                  at               
                               visi.com
Reply to
Grant Edwards

Fine, this explains why the value you read is rotated right by one byte.

You might probably need to do something like

struct { uint8 aByte; union { uint32 aWordArray[16]; uint8 aByteArray[64]; } u; } foo;

In this case foo.u.aWordArray[x] is guaranteed to be word aligned, as the whole union will be.

HTH,

Vadim

Reply to
Vadim Borshchev

There seems to be something a bit kludgy about what I'm about to suggest (I'm not sure why, except there's this Bogus_Variable defined but never used), but could you use a union of a 4-byte 'bogus' unused varuable with the aByteArray, to make the compiler align it? Like this:

struct { uint8 aByte; union { uint32 Bogus_Variable; uint8 aByteArray[ 64 ]; } } foo;

There seems like there ought to be another way to do it, perhaps with a compiler-specific #pragma, but this should work with any compiler.

-----

formatting link

Reply to
Ben Bradley

I think you can force gcc to align the buffer using:

struct { uint8 aByte; uint8 aByteArray[ 64 ] __attribute__ ((aligned (4))); } foo;

(untested)

-- Arne

Reply to
Arne Koewing

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.