IAR C + Motorola = some strange things

Started by lenux22 July 9, 2003

Hello!

We use HCS12 family controller with IAR compiler.

This is a simple code:
--
unsigned char B[4];
unsigned int *ptr;

B[0] = 1;
B[1] = 2;

ptr = ( unsigned int* )B;
---------

After program running *ptr value is 0x0102 instead 0x0201 (what is in common in C/C++). Is any way to fix-it or it's motorola/IAR specific ?

WBR,
Lenux



At 03:42 PM 7/9/2003 +0000, you wrote:

>Hello!
>
>We use HCS12 family controller with IAR compiler.
>
>This is a simple code:
>--
> unsigned char B[4];
> unsigned int *ptr;
>
> B[0] = 1;
> B[1] = 2;
>
> ptr = ( unsigned int* )B;
>---------
>
>After program running *ptr value is 0x0102 instead 0x0201 (what is in
>common in C/C++). Is any way to fix-it or it's motorola/IAR specific ?

Never assume the order in which data will be stored. As you say "what is in
common in C/C++", well, no byte order is not specified in C, neither is
whether adjacent bytes in an array will be contiguous.

You are taking four bytes, telling the compiler that you are actually
dealing with a pointer to an int (how big is a pointer? how big is an int?
that is not specified in the standards either) and assuming that they are
stored in a particular order.

B0 B1 B2 B3 mapped onto ptr would give you B0 B1 (assuming 8 bit chars and
16 bit pointers to n bit ints). On other processors they might be stored as
B1 B0 B3 B2 or B3 B2 B1 B0. It depends on if it is a 32/16/8 bit processor
and which particular architectural decisions were made during design.

Go to a computer dictionary and look up "endian". Unfortunately I can not
find a link to a famous failure where a spacecraft failed due to an endian
mismatch.

Andrei >WBR,
> Lenux >
>-------------------- >
>">http://docs.yahoo.com/info/terms/




This is correct for a Motorola Processor. Motorola storage is msb then lsb
(Big Endian) where as Intel is lsb then msb (Little Endian). PC C/C++
Compilers are designed for Intel Processors!

Here is a good description of Endian:
http://www.cs.umass.edu/~verts/cs32/endian.html

Dave Walters

----- Original Message -----
From: "Andrei Chichak" <>
To: <>
Sent: Wednesday, July 09, 2003 12:28 PM
Subject: Re: [68HC12] IAR C + Motorola = some strange things > At 03:42 PM 7/9/2003 +0000, you wrote:
>
> >Hello!
> >
> >We use HCS12 family controller with IAR compiler.
> >
> >This is a simple code:
> >--
> > unsigned char B[4];
> > unsigned int *ptr;
> >
> > B[0] = 1;
> > B[1] = 2;
> >
> > ptr = ( unsigned int* )B;
> >---------
> >
> >After program running *ptr value is 0x0102 instead 0x0201 (what is in
> >common in C/C++). Is any way to fix-it or it's motorola/IAR specific ?
>
> Never assume the order in which data will be stored. As you say "what is
in
> common in C/C++", well, no byte order is not specified in C, neither is
> whether adjacent bytes in an array will be contiguous.
>
> You are taking four bytes, telling the compiler that you are actually
> dealing with a pointer to an int (how big is a pointer? how big is an int?
> that is not specified in the standards either) and assuming that they are
> stored in a particular order.
>
> B0 B1 B2 B3 mapped onto ptr would give you B0 B1 (assuming 8 bit chars and
> 16 bit pointers to n bit ints). On other processors they might be stored
as
> B1 B0 B3 B2 or B3 B2 B1 B0. It depends on if it is a 32/16/8 bit processor
> and which particular architectural decisions were made during design.
>
> Go to a computer dictionary and look up "endian". Unfortunately I can not
> find a link to a famous failure where a spacecraft failed due to an endian
> mismatch.
>
> Andrei > >WBR,
> > Lenux
> >
> >
> >
> >
> >
> >
> >--------------------
> >
> >
> >
> >">http://docs.yahoo.com/info/terms/ >
> -------------------- >
> ">http://docs.yahoo.com/info/terms/




Welcome to the world of big-endian addressing. You must have started out in
the Intel universe.

This is a typical problem when learning a new CPU architecture, and it has
been around since the minicomputer days, when Digital Equipment Corporation
addressed the least-significant byte of a word as byte 0, as opposed to
IBM's practice of addressing the most-significant byte of a word as byte 0.

Intel followed DEC.

Motorola followed IBM.

It's only a problem when you mix bytewise and wordwise addressing, and it's
one of the first things you have to learn when you start working with a new
CPU, MPU, etc.

/s/jar ()
http://www.mtritter.org
EMAIL DISCLAIMER

Please Note: The information contained in this message may be privileged and
confidential, protected from disclosure, and/or intended only for the use of
the individual or entity named above. If the reader of this message is not
the intended recipient, or an employee or agent responsible for delivering
this message to the intended recipient, you are hereby notified that any
disclosure, distribution, copying or other dissemination of this
communication is strictly prohibited. If you received this communication in
error, please immediately reply to the sender, delete the message and
destroy all copies of it.

Thank You


At 03:11 PM 7/10/2003 -0700, you wrote:
>EXAMPLE 1
>unsigned long datum = 0x01020304

Find cut paste corrections here

>1) address 0x1000 => 0x01 (MSB)

2) address 0x1001 => 0x02
3) address 0x1002 => 0x03
4) address 0x1003 => 0x04 (LSB)

>for an array it looks as follows: >EXAMPLE 2
>
>char array[100] = {0x01,0x02,0x03,0x04};
>
>if you ask for a pointer to the array you will get address 0x1000
>where the base address for big endian points to the MSB

1) address 0x1000 or array+0 => 0x01
2) address 0x1001 or array+1 => 0x02
3) address 0x1002 or array+2 => 0x03
4) address 0x1003 or array+3 => 0x04 (LSB)

>Fred Glaum

Andrei




Hi,

Since motorola is big endian data stuffing looks as follows:

EXAMPLE 1
unsigned long datum = 0x01020304

if you ask for a pointer to a long you will get address 0x1000
where the base address for big endian points to the MSB

1) address 0x1000 => 0x01 (MSB)
2) address 0x1002 => 0x02
3) address 0x1003 => 0x03
4) address 0x1004 => 0x04 (LSB)

for an array it looks as follows: EXAMPLE 2

char array[100] = {0x01,0x02,0x03,0x04};

if you ask for a pointer to the array you will get address 0x1000
where the base address for big endian points to the MSB

1) address 0x1000 or array+1 => 0x01 (MSB)
2) address 0x1002 or array+2 => 0x02
3) address 0x1003 or array+3 => 0x03
4) address 0x1004 or array+4 => 0x04 (LSB)

array element 0 is at address 0x1000
array element 99 is at address 0x1063 Fred Glaum