This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Run-time error in STR instruction

Hi,

Following code:

1:  int main()
2:  {
3:    char Buff[3];
4:    *((short*)(Buff+1)) = 0xFFFF;
5:  }
causes in the 4th string such run-time error:

Non-aligned Access: Thumb Instruction at 00080122H, Memory Access at 000103F9H

Disassembly of the 4th string is:
     4:   *((short*)(Buff+1)) = 0xFFFF;
0x0008011C  4904      LDR       R1,[PC,#0x0010]
0x0008011E  2001      MOV       R0,#0x01
0x00080120  4468      ADD       R0,SP
0x00080122  8001      STRH      R1,[R0,#0x00]
The STRH instruction (address 0x00080122) requires 2-alignment for second operand.
But in this example second operand is not aligned in such manner.

Analogous errors also appear for LDR instruction.

I tested above example with Keil and GNU compilers. Both of them give identical error.

-------------------------------------

With other compilers on other platforms (Borland and I386 for example) such a problem doesn't appear.
It is very convenient to use above method for structures transfer through byte sequence (serial port).
I want to use this method in my work.

How can I use this method on ARM-platform (Keil, GNU compilers)?
How this problem satisfies the ANSI C standart?

Thanks,
Dr. Yuri Tychinsky

Parents
  • For processors that require alignment, it is, as far as I know, always problematic to store entities larger than the slot by typecasting regardless of processor and compiler. This has been true for every processor/compiler set I have worked with when the processor required aligning.

    Erik

Reply
  • For processors that require alignment, it is, as far as I know, always problematic to store entities larger than the slot by typecasting regardless of processor and compiler. This has been true for every processor/compiler set I have worked with when the processor required aligning.

    Erik

Children
  • ANSI does not specify the usage of un-aligned pointers (because the underlaying hardware might not support it).

    The x86 architecture has hardware support for un-aligned accesses.

    The ARM architecture requries software support. Therefore we have implemented the __packed attribute.

    See: http://www.keil.com/support/man/docs/ca/ca_le_packed.htm

    The following code will allow what you want:

    void main(void) {
       char Buff[3];
       *((short __packed *)(Buff+1)) = 0xFFFF;
    }
    

  • "With other compilers on other platforms (Borland and I386 for example) such a problem doesn't appear."

    What is the extent of the testing on which you base this statement?

    "The x86 architecture has hardware support for un-aligned accesses."

    So, even though it "works", the hardware has to jump through hoops and the performance will be degraded. So this technique loses you both performance and portability.
    Thus, the "conventional" method described by Dan may not be as "unattractive" as it appears at first sight...!

  • Andy, Dan, Erik, Reinhard. Thanks for advices.
    I am currently offline and can't discuss in time.

    Of course performance and portability are important criteria.
    But may be other reasons for using bytealigning.
    It is privilege of programmer to decide wich of criteria is more significant.
    For my problem performance and portability are less importance.
    I think that for compiler it is advantageous to give different abilities for programmers.
    And, as Reinhard instructed, the CARM has ability of bytealigning.
    It is what I want.

    Thanks.