Yahoo Groups archive

Lpc2000

Index last updated: 2026-04-28 23:31 UTC

Thread

Un-aligned data access on ARM7 core

Un-aligned data access on ARM7 core

2005-11-16 by Marko Panger

Hello all,

I have a general programming question. Me and my co-workers had an 
discussion about data alignment and non-aligned accesses. Please 
consider the following situation where an un-aligned access was made 
resulting in wrong value.

char buf[5] = {1,2,3,4,5};     

unsigned short tmp;

tmp = *(unsigned short*)&buf[1];       /* &buf[1] is on a odd address

My co-workers expected that tmp will contain the value0x0203, but the 
value was 0x02. I understand that, because ARM7 core does not support 
un-aligned accesses and the compiler was forced to use a word access on 
a odd address. This code was ported from an 8-bit machine where it was, 
off course, working. My question is if all 32-bit devices would have the 
same problem with this code and why when we tested the same situation on 
a PC using Borland Builder compiler it was working as my co-workers 
expected. Is this a CPU(+cpu bus) issue or it is also compiler dependent.

Although I thing this is bad programming practice and it calls for 
errors I am asking if it is possible to enable a warning for such 
situations.

Regards,
Marko

Un-aligned data access on ARM7 core

2005-12-16 by Marko Panger

Hello all,

I have a general programming question. Me and my co-workers had an 
discussion about data alignment and non-aligned accesses. Please 
consider the following situation where an un-aligned access was made 
resulting in wrong value.

char buf[5] = {1,2,3,4,5};    
unsigned short tmp;

tmp = *(unsigned short*)&buf[1];       /* &buf[1] is on a odd address

My co-workers expected that tmp will contain the value0x0203, but the 
value was 0x02. I understand that, because ARM7 core does not support 
un-aligned accesses and the compiler was forced to use a word access on 
a odd address. This code was ported from an 8-bit machine where it was, 
off course, working. My question is if all 32-bit devices would have the 
same problem with this code and why when we tested the same situation on 
a PC using Borland Builder compiler it was working as my co-workers 
expected. Is this a CPU(+cpu bus) issue or it is also compiler dependent.

Although I thing this is bad programming practice and it calls for 
errors I am asking if it is possible to enable a warning for such 
situations.

Regards,
Marko

Re: [lpc2000] Un-aligned data access on ARM7 core

2005-12-16 by Tom Walsh

Marko Panger wrote:

>Hello all,
>
>I have a general programming question. Me and my co-workers had an 
>discussion about data alignment and non-aligned accesses. Please 
>consider the following situation where an un-aligned access was made 
>resulting in wrong value.
>
>char buf[5] = {1,2,3,4,5};     
>
>unsigned short tmp;
>
>tmp = *(unsigned short*)&buf[1];       /* &buf[1] is on a odd address
>
>My co-workers expected that tmp will contain the value0x0203, but the 
>value was 0x02. I understand that, because ARM7 core does not support 
>un-aligned accesses and the compiler was forced to use a word access on 
>a odd address. This code was ported from an 8-bit machine where it was, 
>off course, working. My question is if all 32-bit devices would have the 
>same problem with this code and why when we tested the same situation on 
>a PC using Borland Builder compiler it was working as my co-workers 
>expected. Is this a CPU(+cpu bus) issue or it is also compiler dependent
>
X86 is about the only 32bit processor that I know of that will access 
longs / words on uneven boundries.  Almost all other families of 32bit 
processors have the limitation of accessing longs / words on their 
respective boundries.  The X86 is the oddball of the computer world.

Regards,

TomW

>.
>
>Although I thing this is bad programming practice and it calls for 
>errors I am asking if it is possible to enable a warning for such 
>situations.
>
>Regards,
>Marko
>
>
>
>
>
> 
>Yahoo! Groups Links
>
>
>
> 
>
>
>  
>


-- 
Tom Walsh - WN3L - Embedded Systems Consultant
http://openhardware.net, http://cyberiansoftware.com
"Windows? No thanks, I have work to do..."
----------------------------------------------------

Re: [lpc2000] Un-aligned data access on ARM7 core

2005-12-16 by Richard

When you use an explicit cast, you are telling the compiler that you know 
what you are doing and the compiler should leave you alone, so that's what 
it did. For example, if you always ensure that the buf starts at an even 
address, and that you only do things like
         tmp = *(unsigned short *)&buf[i];
where i is even, then the warning would be unnecessary.

Bottom line - casts should not be used willy nilly without fully 
understanding what's happening.

At 01:17 PM 11/16/2005, Marko Panger wrote:

>Hello all,
>
>I have a general programming question. Me and my co-workers had an
>discussion about data alignment and non-aligned accesses. Please
>consider the following situation where an un-aligned access was made
>resulting in wrong value.
>
>char buf[5] = {1,2,3,4,5};
>
>unsigned short tmp;
>
>tmp = *(unsigned short*)&buf[1];       /* &buf[1] is on a odd address
>
>My co-workers expected that tmp will contain the value0x0203, but the
>value was 0x02. I understand that, because ARM7 core does not support
>un-aligned accesses and the compiler was forced to use a word access on
>a odd address. This code was ported from an 8-bit machine where it was,
>off course, working. My question is if all 32-bit devices would have the
>same problem with this code and why when we tested the same situation on
>a PC using Borland Builder compiler it was working as my co-workers
>expected. Is this a CPU(+cpu bus) issue or it is also compiler dependent.
>
>Although I thing this is bad programming practice and it calls for
>errors I am asking if it is possible to enable a warning for such
>situations.
>
>Regards,
>Marko
>
>

// richard (This email is for mailing lists. To reach me directly, please 
use richard at imagecraft.com)

Re: [lpc2000] Un-aligned data access on ARM7 core

2005-12-17 by Robert Adsett

At 10:22 PM 12/16/05 +0100, Marko Panger wrote:
>I have a general programming question. Me and my co-workers had an
>discussion about data alignment and non-aligned accesses. Please
>consider the following situation where an un-aligned access was made
>resulting in wrong value.
>
>char buf[5] = {1,2,3,4,5};
>unsigned short tmp;
>
>tmp = *(unsigned short*)&buf[1];       /* &buf[1] is on a odd address
>
>My co-workers expected that tmp will contain the value0x0203, but the
>value was 0x02. I understand that, because ARM7 core does not support
>un-aligned accesses and the compiler was forced to use a word access on
>a odd address. This code was ported from an 8-bit machine where it was,
>off course, working. My question is if all 32-bit devices would have the
>same problem with this code and why when we tested the same situation on
>a PC using Borland Builder compiler it was working as my co-workers
>expected. Is this a CPU(+cpu bus) issue or it is also compiler dependent.

Compiler, micro and possibly more could play a role.  ANSI and ISO give the 
compiler leeway to do just about anything at this point.  Some micros will 
have a bus fault, some will read the incorrect value and some will read the 
'correct' value.  Note that whether the problem shows up may also depend on 
what else is in memory since the compiler is certainly free to place buf 
such that it starts on an odd address at which point buf[1] is suddenly on 
an even address.  Of course on a recompile it might change.  All of a 
sudden you have yourself a Heisenbug.

The correct value at this point is also open to question even if alignment 
isn't an issue since that still leaves byte ordering and that varies across 
micros.

>Although I thing this is bad programming practice and it calls for
>errors I am asking if it is possible to enable a warning for such
>situations.

Yes, but the cast will likely trip you up.  PC-Lint gives me a warning 
about a cast from a pointer to a pointer but  that is probably not a 
sufficient warning.

Depending on what you are trying to do there are alternatives that will 
work reasonably portably.

Robert

" 'Freedom' has no meaning of itself.  There are always restrictions,   be 
they legal, genetic, or physical.  If you don't believe me, try to chew a 
radio signal. "  -- Kelvin Throop, III
http://www.aeolusdevelopment.com/

Re: [lpc2000] Un-aligned data access on ARM7 core

2005-12-17 by Marko Panger

Hi,

Your replies are just what I was looking for. I needed a confirmation of 
my understanding and I got it. For me, is normal not to receive a 
warning in this situation because the compiler was forced by you. And 
yes, different micros will react differently. Some will issue bus error, 
some will read incorrect value and so on. My co-workers claimed up on 
the micro and compiler that this should be handled but I really can't 
imagine how if the compiler was forced.

This code was ported from an 8 bit machine (with 8 bit data bus) when 
such things works regardless of "buf" alignment, because buf is accessed 
every time 8 bit, regardless of the cast.

The only thing that I was surprised was my PC box where this was possible.

My conclusion is that un-supported un-aligned accesses are not 
compiler/cpu bug but are compiler/cpu FEATURE and a skilled programmers 
should RTFM and be aware of this.

Thanks for you replies !

marko

Robert Adsett wrote:

>At 10:22 PM 12/16/05 +0100, Marko Panger wrote:
>  
>
>>I have a general programming question. Me and my co-workers had an
>>discussion about data alignment and non-aligned accesses. Please
>>consider the following situation where an un-aligned access was made
>>resulting in wrong value.
>>
>>char buf[5] = {1,2,3,4,5};
>>unsigned short tmp;
>>
>>tmp = *(unsigned short*)&buf[1];       /* &buf[1] is on a odd address
>>
>>My co-workers expected that tmp will contain the value0x0203, but the
>>value was 0x02. I understand that, because ARM7 core does not support
>>un-aligned accesses and the compiler was forced to use a word access on
>>a odd address. This code was ported from an 8-bit machine where it was,
>>off course, working. My question is if all 32-bit devices would have the
>>same problem with this code and why when we tested the same situation on
>>a PC using Borland Builder compiler it was working as my co-workers
>>expected. Is this a CPU(+cpu bus) issue or it is also compiler dependent.
>>    
>>
>
>Compiler, micro and possibly more could play a role.  ANSI and ISO give the 
>compiler leeway to do just about anything at this point.  Some micros will 
>have a bus fault, some will read the incorrect value and some will read the 
>'correct' value.  Note that whether the problem shows up may also depend on 
>what else is in memory since the compiler is certainly free to place buf 
>such that it starts on an odd address at which point buf[1] is suddenly on 
>an even address.  Of course on a recompile it might change.  All of a 
>sudden you have yourself a Heisenbug.
>
>The correct value at this point is also open to question even if alignment 
>isn't an issue since that still leaves byte ordering and that varies across 
>micros.
>
>  
>
>>Although I thing this is bad programming practice and it calls for
>>errors I am asking if it is possible to enable a warning for such
>>situations.
>>    
>>
>
>Yes, but the cast will likely trip you up.  PC-Lint gives me a warning 
>about a cast from a pointer to a pointer but  that is probably not a 
>sufficient warning.
>
>Depending on what you are trying to do there are alternatives that will 
>work reasonably portably.
>
>Robert
>
>" 'Freedom' has no meaning of itself.  There are always restrictions,   be 
>they legal, genetic, or physical.  If you don't believe me, try to chew a 
>radio signal. "  -- Kelvin Throop, III
>http://www.aeolusdevelopment.com/
>
>
>
>
> 
>Yahoo! Groups Links
>
>
>
> 
>
>
>
>  
>



[Non-text portions of this message have been removed]

Re: [lpc2000] Un-aligned data access on ARM7 core

2005-12-17 by Tom Walsh

Richard wrote:

>When you use an explicit cast, you are telling the compiler that you know 
>what you are doing and the compiler should leave you alone, so that's what 
>it did. For example, if you always ensure that the buf starts at an even 
>address, and that you only do things like
>         tmp = *(unsigned short *)&buf[i];
>where i is even, then the warning would be unnecessary.
>
>Bottom line - casts should not be used willy nilly without fully 
>understanding what's happening.
>
>  
>

Yeah, reminds me about something I did with a cast recently to extract a 
long from char array (buffer).  I cast the heck out of that reference to 
the char array and gcc did let me extract a long from it..  On an uneven 
boundry, the processor (LPC2138) didn't throw an exception, but it sort 
of got "a value" from the array, but the not the value I was expecting!  
Heh, the upper byte (MSD) was, how shall I say it, "wrong". heh

I learned my lesson about coercing gcc + ARM to do some things with type 
casts.  Now I'm a little more conservative about how I cast references 
to objects.

Regards,

TomW



>At 01:17 PM 11/16/2005, Marko Panger wrote:
>
>  
>
>>Hello all,
>>
>>I have a general programming question. Me and my co-workers had an
>>discussion about data alignment and non-aligned accesses. Please
>>consider the following situation where an un-aligned access was made
>>resulting in wrong value.
>>
>>char buf[5] = {1,2,3,4,5};
>>
>>unsigned short tmp;
>>
>>tmp = *(unsigned short*)&buf[1];       /* &buf[1] is on a odd address
>>
>>My co-workers expected that tmp will contain the value0x0203, but the
>>value was 0x02. I understand that, because ARM7 core does not support
>>un-aligned accesses and the compiler was forced to use a word access on
>>a odd address. This code was ported from an 8-bit machine where it was,
>>off course, working. My question is if all 32-bit devices would have the
>>same problem with this code and why when we tested the same situation on
>>a PC using Borland Builder compiler it was working as my co-workers
>>expected. Is this a CPU(+cpu bus) issue or it is also compiler dependent.
>>
>>Although I thing this is bad programming practice and it calls for
>>errors I am asking if it is possible to enable a warning for such
>>situations.
>>
>>Regards,
>>Marko
>>
>>
>>    
>>
>
>// richard (This email is for mailing lists. To reach me directly, please 
>use richard at imagecraft.com) 
>
>
>
>
> 
>Yahoo! Groups Links
>
>
>
> 
>
>
>  
>


-- 
Tom Walsh - WN3L - Embedded Systems Consultant
http://openhardware.net, http://cyberiansoftware.com
"Windows? No thanks, I have work to do..."
----------------------------------------------------

Re: [lpc2000] Un-aligned data access on ARM7 core

2005-12-17 by Tom Walsh

Marko Panger wrote:

>Hi,
>
>Your replies are just what I was looking for. I needed a confirmation of 
>my understanding and I got it. For me, is normal not to receive a 
>warning in this situation because the compiler was forced by you. And 
>yes, different micros will react differently. Some will issue bus error, 
>some will read incorrect value and so on. My co-workers claimed up on 
>the micro and compiler that this should be handled but I really can't 
>imagine how if the compiler was forced.
>
>This code was ported from an 8 bit machine (with 8 bit data bus) when 
>such things works regardless of "buf" alignment, because buf is accessed 
>every time 8 bit, regardless of the cast.
>
>  
>
Yes, you can do that too with the ARM processor, but you describe that 
type of data as "__attribute__((packed))"  to signal the compiler to 
treat the structure differently.  With a 'packed' attribute, the 
accesses to various parts of the structure may be done on a long, word  
by word, or byte by byte basis, depending.

TomW


>The only thing that I was surprised was my PC box where this was possible.
>
>My conclusion is that un-supported un-aligned accesses are not 
>compiler/cpu bug but are compiler/cpu FEATURE and a skilled programmers 
>should RTFM and be aware of this.
>
>Thanks for you replies !
>
>marko
>
>Robert Adsett wrote:
>
>  
>
>>At 10:22 PM 12/16/05 +0100, Marko Panger wrote:
>> 
>>
>>    
>>
>>>I have a general programming question. Me and my co-workers had an
>>>discussion about data alignment and non-aligned accesses. Please
>>>consider the following situation where an un-aligned access was made
>>>resulting in wrong value.
>>>
>>>char buf[5] = {1,2,3,4,5};
>>>unsigned short tmp;
>>>
>>>tmp = *(unsigned short*)&buf[1];       /* &buf[1] is on a odd address
>>>
>>>My co-workers expected that tmp will contain the value0x0203, but the
>>>value was 0x02. I understand that, because ARM7 core does not support
>>>un-aligned accesses and the compiler was forced to use a word access on
>>>a odd address. This code was ported from an 8-bit machine where it was,
>>>off course, working. My question is if all 32-bit devices would have the
>>>same problem with this code and why when we tested the same situation on
>>>a PC using Borland Builder compiler it was working as my co-workers
>>>expected. Is this a CPU(+cpu bus) issue or it is also compiler dependent.
>>>   
>>>
>>>      
>>>
>>Compiler, micro and possibly more could play a role.  ANSI and ISO give the 
>>compiler leeway to do just about anything at this point.  Some micros will 
>>have a bus fault, some will read the incorrect value and some will read the 
>>'correct' value.  Note that whether the problem shows up may also depend on 
>>what else is in memory since the compiler is certainly free to place buf 
>>such that it starts on an odd address at which point buf[1] is suddenly on 
>>an even address.  Of course on a recompile it might change.  All of a 
>>sudden you have yourself a Heisenbug.
>>
>>The correct value at this point is also open to question even if alignment 
>>isn't an issue since that still leaves byte ordering and that varies across 
>>micros.
>>
>> 
>>
>>    
>>
>>>Although I thing this is bad programming practice and it calls for
>>>errors I am asking if it is possible to enable a warning for such
>>>situations.
>>>   
>>>
>>>      
>>>
>>Yes, but the cast will likely trip you up.  PC-Lint gives me a warning 
>>about a cast from a pointer to a pointer but  that is probably not a 
>>sufficient warning.
>>
>>Depending on what you are trying to do there are alternatives that will 
>>work reasonably portably.
>>
>>Robert
>>
>>" 'Freedom' has no meaning of itself.  There are always restrictions,   be 
>>they legal, genetic, or physical.  If you don't believe me, try to chew a 
>>radio signal. "  -- Kelvin Throop, III
>>http://www.aeolusdevelopment.com/
>>
>>
>>
>>
>>
>>Yahoo! Groups Links
>>
>>
>>
>>
>>
>>
>>
>> 
>>
>>    
>>
>
>
>
>[Non-text portions of this message have been removed]
>
>
>
>
> 
>Yahoo! Groups Links
>
>
>
> 
>
>
>  
>


-- 
Tom Walsh - WN3L - Embedded Systems Consultant
http://openhardware.net, http://cyberiansoftware.com
"Windows? No thanks, I have work to do..."
----------------------------------------------------

Re: [lpc2000] Un-aligned data access on ARM7 core

2005-12-17 by Robert Adsett

At 09:52 AM 12/17/05 +0100, Marko Panger wrote:
>Your replies are just what I was looking for. I needed a confirmation of
>my understanding and I got it. For me, is normal not to receive a
>warning in this situation because the compiler was forced by you. And
>yes, different micros will react differently. Some will issue bus error,
>some will read incorrect value and so on. My co-workers claimed up on
>the micro and compiler that this should be handled but I really can't
>imagine how if the compiler was forced.
>
>This code was ported from an 8 bit machine (with 8 bit data bus) when
>such things works regardless of "buf" alignment, because buf is accessed
>every time 8 bit, regardless of the cast.
>
>The only thing that I was surprised was my PC box where this was possible.

PCs and PC programmers tend to allow and encourage a lot of things that are 
very bad practice in the embedded world.  Arguably they are bad even in the 
PC world but the costs are low.


>My conclusion is that un-supported un-aligned accesses are not
>compiler/cpu bug but are compiler/cpu FEATURE and a skilled programmers
>should RTFM and be aware of this.


Yep, and one thing I didn't point out earlier is that your example also 
appears to depend on the sizes of both char and short which are not 
guaranteed to be specific sizes.  They often are 8 bits and 16bits 
respectively but both can be larger.

Robert

" 'Freedom' has no meaning of itself.  There are always restrictions,   be 
they legal, genetic, or physical.  If you don't believe me, try to chew a 
radio signal. "  -- Kelvin Throop, III
http://www.aeolusdevelopment.com/

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.