Reputation: 49
I am using TM4C123 evaluation board(cortex M4f Based) and trying to compile the project using different toolchains. GCC assembler generates an error for these instructions which I couldn't resolve or use a different instructions :
POP {R4-R11}
POP {R12}
POP LR
STMDB R2!, {R4 - R11} @ Stacking R4-->R11
LDMIA R2!, {R4 - R11} @ unStacking R4-->R11
Known that the POP instruction was acceptable when used to pop R0-R3 or R12 Could you help or refer to any alternative instructions?
Upvotes: 2
Views: 2687
Reputation: 71536
Being a cortex-m there are limitations: please read the documentation first, both for the processor core and the assembler. Assembly language is defined by the assembler, the tool, not the target; there's no reason to assume that for the same target assembly languages are portable across tools.
In normal thumb T1 encoding in the docs you can only push r0-r7, T2 which the m4 supports r0-r12, and T3 is for one register at a time also thumb2 which the m4 supports. Then the PC and LR are mixed in there. What does your disassembly show and what commands are you using to build this? What cpu have you specified?
.cpu cortex-m4
.thumb
POP {R4-R11}
POP {R12}
POP LR
STMDB R2!, {R4 - R11} @ Stacking R4-->R11
LDMIA R2!, {R4 - R11} @ unStacking R4-->R11
arm-none-eabi-as so.s -o so.o
so.s: Assembler messages:
so.s:4: Error: invalid register list to push/pop instruction -- `pop {R4-R11}'
so.s:5: Error: invalid register list to push/pop instruction -- `pop {R12}'
so.s:6: Error: expression too complex -- `pop LR'
so.s:7: Error: lo register required -- `stmdb R2!,{R4-R11}'
so.s:8: Error: lo register required -- `ldmia R2!,{R4-R11}'
then
.cpu cortex-m4
.thumb
POP {R4,R5,R6,R7,R8,R9,R10,R11}
POP {R12}
POP LR
STMDB R2!, {R4,R5,R6,R7,R8,R9,R10,R11} @ Stacking R4-->R11
LDMIA R2!, {R4,R5,R6,R7,R8,R9,R10,R11} @ unStacking R4-->R11
so.s: Assembler messages:
so.s:4: Error: invalid register list to push/pop instruction -- `pop {R4,R5,R6,R7,R8,R9,R10,R11}'
so.s:5: Error: invalid register list to push/pop instruction -- `pop {R12}'
so.s:6: Error: expression too complex -- `pop LR'
so.s:7: Error: lo register required -- `stmdb R2!,{R4,R5,R6,R7,R8,R9,R10,R11}'
so.s:8: Error: lo register required -- `ldmia R2!,{R4,R5,R6,R7,R8,R9,R10,R11}'
and the tool is telling you the problems so refer to the instruction set documentation to find out what you did wrong.
Now I prefer not to use unified syntax and don't normally write thumb2 instructions in asm, but if so then for gnu you really should set for unified syntax.
.cpu cortex-m4
.syntax unified
.thumb
POP {R4,R5,R6,R7,R8,R9,R10,R11}
POP {R12}
POP LR
STMDB R2!, {R4,R5,R6,R7,R8,R9,R10,R11} @ Stacking R4-->R11
LDMIA R2!, {R4,R5,R6,R7,R8,R9,R10,R11} @ unStacking R4-->R11
arm-none-eabi-as so.s -o so.o
so.s: Assembler messages:
so.s:7: Error: expression too complex -- `pop LR'
that plus the cpu enables using thumb2 instructions, and again read what the tool is telling you
.cpu cortex-m4
.syntax unified
.thumb
POP {R4,R5,R6,R7,R8,R9,R10,R11}
POP {R12}
POP {LR}
STMDB R2!, {R4,R5,R6,R7,R8,R9,R10,R11} @ Stacking R4-->R11
LDMIA R2!, {R4,R5,R6,R7,R8,R9,R10,R11} @ unStacking R4-->R11
00000000 <.text>:
0: e8bd 0ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, r10, r11}
4: f85d cb04 ldr.w r12, [sp], #4
8: f85d eb04 ldr.w lr, [sp], #4
c: e922 0ff0 stmdb r2!, {r4, r5, r6, r7, r8, r9, r10, r11}
10: e8b2 0ff0 ldmia.w r2!, {r4, r5, r6, r7, r8, r9, r10, r11}
Note the tool chose to give you the equivalent using ldr instead of pop. (push and pop are pseudo instructions in thumb they are really stm/ldm just like full sized arm)
For grins:
push {r0,lr}
push {r0,r1}
pop {r0,pc}
pop {r0,r1}
14: b501 push {r0, lr}
16: b403 push {r0, r1}
18: bd01 pop {r0, pc}
1a: bc03 pop {r0, r1}
so the M/P bits in the encoding do appear to be used for pc/lr
Upvotes: 3