kanghao chen
kanghao chen

Reputation: 99

Questions about non-byte aligned access of STM32F4 series MCU

Recently I encountered a bug in non-aligned byte access, so I did an experiment and encountered some doubts, as follows:

  1. Why does the system not crash when my code below accesses non-aligned bytes?

  2. Under what circumstances will the starting address of the unsigned char buff variable be a multiple of 2 instead of a multiple of 4?

The ARMCC compiler I use does not enable compiler optimization.

struct xxx {
    unsigned char a;
    unsigned char b;
    unsigned char c;
    unsigned int d;
    unsigned char e;
    unsigned char f;
}__attribute__((packed));
unsigned char buff[100];

int main()
{
    struct xxx aaa;
    aaa.d = 0xffffffff;
    return 0;
}

Upvotes: 1

Views: 57

Answers (3)

Ehsan Daneshvar
Ehsan Daneshvar

Reputation: 11

usually compiler assume void address between none aligned structure and class arrangements. if you check size of your structure with sizeof(your_type) command you would see the real size in memory is 12bytes. something like this:

 struct your_type{

    //first word
    unsigned char a;
    unsigned char b;
    unsigned char c;
    unsigned char _shadowbyte_1;

    //second word
    unsigned int d;

    //third word 
    unsigned char e;
    unsigned char f;
    unsigned char _shadow_byte_2;
    unsigned char _shadow_byte_3;
    };

Upvotes: 0

Clifford
Clifford

Reputation: 93566

Cortex-M4 supports unaligned access. Such access will result in multiple aligned bus transactions so are less efficient, but nonetheless transparent at the instruction level.

Ref: Unaligned accesses that cross regions

Even if unaligned access were not intrinsically supported, presented with your test code, a compiler would simply generate suitable additional code to load the unaligned word into a single register.

It does not apply in the case of an M4 but to force an unaligned access without the compiler "fixing" it for you, consider;

volatile uint32_t mem[] = { 0x76543210, 0xFEDCBA98 } ;
volatile uint32_t* unaligned = ((char*)mem) + 1);
volatile uint32_t val = *unaligned ;

On a little-endian processor supporting unaligned access val will be 0x87654321. If the access is not supported, you might then expect a runtime error.

Upvotes: 2

GandhiGandhi
GandhiGandhi

Reputation: 1350

Why does the system not crash when my code below accesses non-aligned bytes?

Why do you think it would? ARM has STRB/LDRB instructions for moving single bytes from registers to memory and vice versa.

Upvotes: -1

Related Questions