ldr wrong relative address calculation
First of all - I'm a beginner in arm assembler. I'm trying to implement saving exception info in c project. Handler is written as an inline assembler inside c code. Idea is to extract relevant information from the exception stack frame and store it for later inspection. After that I would reset the CPU.
Everything seems to work fine except that I discovered strange behaviour with generated asm code which made me think if I have some ground level misunderstanding.
CPU: EFM32JG1B200F25
Compiler: arm-none-eabi-g++ (GNU Tools for Arm Embedded Processors 7-2018-q2-update) 7.3.1 20180622 (release) [ARM/embedded-
This is a function that I'm using to extract an active stack (from EXC_RETURN that is stored in LR during exception) and then another function 'save_stack_frame' (source not shown here) is responsible for extracting and storing stack frame info.
__attribute_
__USED static void
handle_
{
__asm volatile(
"tst lr, #4 \n"
"ite eq \n"
"mrseq r0, msp \n"
"mrsne r0, psp \n"
"ldr r1, save_stack_
"bx r1 \n"
"save_
}
Sometime above code will produce valid and sometimes invalid ldr pc relative offset. After experimentation I discovered that if a linker puts function on word boundary then instruction is ok but if function ends on half word address then the result becomes invalid. Calling invalid version will end up as jump (BX) to the wrong address.
If I put ".align 2\n" as a first instruction in handle_exception function or if linker puts function in word aligned address then everything works.
I would like to know the reason why this is happening? Is it a bug in the compiler or do I have to manage function and/or data alignment for myself? And in that case which alignment is wrong here?
000085ce <handle_
"ite eq \n"
"mrseq r0, msp \n"
"mrsne r0, psp \n"
"ldr r1, save_stack_
"bx r1 \n"
"save_
85ce: f01e 0f04 tst.w lr, #4
85d2: bf0c ite eq
85d4: f3ef 8008 mrseq r0, MSP
85d8: f3ef 8009 mrsne r0, PSP
85dc: f8df 1004 ldr.w r1, [pc, #4] ; 85e4 <save_stack_
85e0: 4708 bx r1
000085e2 <save_stack_
85e2: 8549 .short 0x8549
85e4: 0000 .short 0x0000
}
Valid version:
000085d0 <handle_
"ite eq \n"
"mrseq r0, msp \n"
"mrsne r0, psp \n"
"ldr r1, save_stack_
"bx r1 \n"
"save_
85d0: f01e 0f04 tst.w lr, #4
85d4: bf0c ite eq
85d6: f3ef 8008 mrseq r0, MSP
85da: f3ef 8009 mrsne r0, PSP
85de: f8df 1004 ldr.w r1, [pc, #4] ; 85e4 <save_stack_
85e2: 4708 bx r1
000085e4 <save_stack_
85e4: 00008549 .word 0x00008549
}
Question information
- Language:
- English Edit question
- Status:
- Expired
- Assignee:
- No assignee Edit question
- Last query:
- Last reply: