Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ARM Cortex M7 unaligned access and memcpy

I am compiling this code for a Cortex M7 using GCC:

// copy manually
void write_test_plain(uint8_t * ptr, uint32_t value)
{
    *ptr++ = (u8)(value);
    *ptr++ = (u8)(value >> 8);
    *ptr++ = (u8)(value >> 16);
    *ptr++ = (u8)(value >> 24); 
}

// copy using memcpy
void write_test_memcpy(uint8_t * ptr, uint32_t value)
{
    void *px = (void*)&value;
    memcpy(ptr, px, 4);
}

int main(void) 
{
    extern uint8_t data[];
    extern uint32_t value;

    // i added some offsets to data to
    // make sure the compiler cannot
    // assume it's aligned in memory

    write_test_plain(data + 2, value);
    __asm volatile("": : :"memory"); // just to split inlined calls
    write_test_memcpy(data + 5, value);

    ... do something with data ...
}

And I get the following Thumb2 assembly with -O2:

// write_test_plain(data + 2, value);
800031c:    2478        movs    r4, #120 ; 0x78
800031e:    2056        movs    r0, #86  ; 0x56
8000320:    2134        movs    r1, #52  ; 0x34
8000322:    2212        movs    r2, #18  ; 0x12
8000324:    759c        strb    r4, [r3, #22]
8000326:    75d8        strb    r0, [r3, #23]
8000328:    7619        strb    r1, [r3, #24]
800032a:    765a        strb    r2, [r3, #25]

// write_test_memcpy(data + 5, value);
800032c:    4ac4        ldr r2, [pc, #784]  ; (8000640 <main+0x3a0>)
800032e:    923b        str r2, [sp, #236]  ; 0xec
8000330:    983b        ldr r0, [sp, #236]  ; 0xec
8000332:    f8c3 0019   str.w   r0, [r3, #25]

Can someone explain how the memcpy version works? This looks like inlined 32-bit store to the destination address, but isn't this a problem since data + 5 is most certainly not aligned to a 4-byte boundary?

Is this perhaps some optimization which happens due to some undefined behavior in my source?

like image 721
Lou Avatar asked Jun 14 '18 22:06

Lou


People also ask

Does ARM support unaligned access?

ARM processors do not provide support for unaligned doubleword accesses, for example unaligned accesses to long long integers. Doubleword accesses must be either eight-byte or four-byte aligned. The compiler does not provide support for modulo eight-byte alignment checking.

What is the difference between ARM and Cortex?

On Cortex-M, you can write an interrupt routine directly in C like any other subroutine, without adding any special attribute keywords. On Arm7, your compiler need to add a special prologue/epilogue. The prologue/epilogue mainly saves and restores registers on the stack.

Is ARM Cortex m4 a RISC or CISC?

The ARM Cortex-M is a group of 32-bit RISC ARM processor cores licensed by Arm Holdings.

What is hard fault error?

HardFault refers to all classes of faults that cannot be handled by any of the other exception mechanisms. Typically, HardFault is used for unrecoverable system failures.


2 Answers

For Cortex-M processors unaligned loads and stores of bytes, half-words, and words are usually allowed and most compilers use this when generating code unless they are instructed not to. If you want to prevent gcc from assuming the unaligned accesses are OK, you can use the -mno-unaligned-access compiler flag.

If you specify this flag gcc will no longer inline the call to memcpy and write_test_memcpy looks like

write_test_memcpy(unsigned char*, unsigned long):
  push {lr}
  sub sp, sp, #12
  movs r2, #4
  add r3, sp, #8
  str r1, [r3, #-4]!
  mov r1, r3
  bl memcpy
  add sp, sp, #12
  ldr pc, [sp], #4
like image 200
Johan Avatar answered Oct 03 '22 01:10

Johan


Cortex-M 7 , M4, M3 M33, M23 does support unaligned access M0, M+ doesn't support unaligned access

however you can disable the support of unaligned access in cortexm7 by setting bit UNALIGN_TRP in configuration and control register and any unaligned access will generate usage fault.

From compiler perspective, default setting is that generated assembly code does unaligned access unless you disable this by using the compile flag -mno-unaligned-access

like image 26
dhokar.w Avatar answered Oct 03 '22 01:10

dhokar.w