Re: quick question

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I am 99% sure that if you did this test on an old 68000 type platform before 68020(?), it would not work. Somewhere in the 68000 genealogy, they added unaligned access.

I believe if you tried this on the old IBM RT it would not work.

I was recently consulted on a problem the client could not solve. It turned out that it was a modern day controller chip (single chip computer type thing) that was still based on the 68010 engine. The problem was the code was getting an "odd address exception" because it was accessing an unaligned word.

BUT... this is 2006... most machines today have the ability to access unaligned data -- but it does cost you in performance. Also, the atomic operations (fetch_and_set, fetch_and_add, etc) I know of no platform can do atomic operations on unaligned data.

So, it just depends upon where this is going to be used. It also depends upon why you are doing this in the first place.

On Feb 16, 2006, at 8:57 AM, Jim Stapleton wrote:

I remember reading that there are systems where they don't like basic
variables to be put on offsets that are not an integer multiple of the
variable size, up to variables the size of a system word.

example, if this applied to the 32 bit x86 architechture where a word
is defined as 4 bytes (I'm talking about the actual arch here, and not
the bastardized useage form 16bit ASM):
char [1 byte]: can be anywhere
short [2 bytes]: any 2N address, where N is an integer, and N > 0.
int/long [4 bytes]: any 4N address, where N is an integer, and N > 0
long long [8 bytes]: any 4N address, where N is an integer, and N > 0
(8 bytes > 1 word)


Now, this set of code works on the x86 platform, but I'm worried it
may not work on other platforms, am I correct in this worry?

#include <stdio.h>

=======================================================
int main()
{
  char test[] =  {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a};
  char *tptr = test;
  int *ptr;

  ptr = (int*)tptr;
  printf("tptr[0]: %x\n", *ptr);

  tptr++;
  ptr = (int*)tptr;
  printf("tptr[1]: %x\n", *ptr);

  tptr++;
  ptr = (int*)tptr;
  printf("tptr[2]: %x\n", *ptr);

  tptr++;
  ptr = (int*)tptr;
  printf("tptr[3]: %x\n", *ptr);

  return 0;
}
=======================================================

output (note: all my machines are 32 bit x86, so this output is
correct for them, on reasonable endian machines, the bytes in the
output would be reversed):
tptr[0]: 3020100
tptr[1]: 4030201
tptr[2]: 5040302
tptr[3]: 6050403



Thanks
-Jim



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux