I just found an insidious and disconcerting characteristic of the uVision3 ARM compiler V3.12a. I have inherited C code to migrate to the ARM processor. This C code uses unsigned char pointers quite liberally to pass the address of data back and forth. The code, of course, casts these generic unsigned char pointers to various data types to access the underlying data. I have found that if the unsigned char point happens to be pointing at a odd address and it is cast to a short type pointer (e.g., "*(SHORT*)p"), the compiler will resolve the address the previous even address. For a simplistic example, if the address of unsigned char *p happens to be 0x5 and the following code is executed:
unsigned char *p; ... *(unsigned short*)p = 0;
I've been on vacation (hence the delay in this response) but I do want to relay an acceptable technique I have found to solve my alignment problems, should any other unfortunate programmers be forced to work with inherited code, such as is our case. As stated previously, the problem is casting generic unsigned char (8-bit) pointers to larger data types, such as this:
unsigned char *p; ... *(__packed unsigned short*)p = 0;
"This solution requires some careful editing,..." I recommend you use a macro, with conditional compilation, and continually re-check that it still builds (and works!) on the previous target:
#ifdef __CA__ // Keil CARM Compiler #define UNALIGNED __packed #else // The "other" compiler #define UNALIGNED_UNSIGNED_SHORT #endif : *(UNALIGNED unsigned short*)p = 0;