我正在使用TM4C123评估板(基于cortex M4f(,并试图使用不同的工具链编译项目。GCC汇编程序为这些指令生成了一个错误,我无法解决或使用不同的指令:
POP {R4-R11}
POP {R12}
POP LR
STMDB R2!, {R4 - R11} @ Stacking R4-->R11
LDMIA R2!, {R4 - R11} @ unStacking R4-->R11
已知POP指令在用于弹出R0-R3或R12时是可接受的你能帮忙或参考其他说明吗?
作为一个cortex-m有一些限制:请先阅读处理器核心和汇编程序的文档。汇编语言是由汇编程序、工具而不是目标定义的;没有理由假设对于相同的目标汇编语言可以跨工具移植。
在文档中的普通thumb T1编码中,您只能推送r0-r7,m4支持r0-r12的T2,T3一次用于一个寄存器,m4也支持thumb 2。然后PC和LR混合在一起。你的反汇编显示了什么?你用什么命令来构建它?你指定了什么cpu?
.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}'
然后
.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}'
该工具会告诉你问题所在,所以请参阅说明集文档,找出你做错了什么。
现在我不喜欢使用统一语法,通常也不在asm中编写thumb2指令,但如果是这样,那么对于gnu,你真的应该设置统一语法。
.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'
再加上cpu可以使用thumb2指令,并再次读取工具告诉你的
.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}
请注意,该工具选择使用ldr而不是pop来为您提供等效功能。(push和pop是拇指中的伪指令,它们实际上是stm/ldm,就像全尺寸的手臂一样(
用于研磨:
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}
因此,编码中的M/p位似乎确实用于pc/lr