我准备为cortex-m4优化一些代码(仅限教育版),所以我写了这样的简单内联函数:
inline int8_t recalculate_val(uint16_t ADC_val){
int16_t value;
value += fuzzywynik1 + ADC_val;
return value;
}
现在,当我预览asm代码时,我可以看到很多我无法理解的内容:
0x08002618 F44F7081 MOV r0,#0x102
0x0800261C E04A B 0x080026B4
0x0800261E E04C B 0x080026BA
0x08002620 006A DCW 0x006A
0x08002622 2000 DCW 0x2000
0x08002624 0024 DCW 0x0024
0x08002626 2000 DCW 0x2000
0x08002628 0C2C DCW 0x0C2C
0x0800262A 4000 DCW 0x4000
0x0800262C 0004 DCW 0x0004
0x0800262E 0040 DCW 0x0040
0x08002630 0800 DCW 0x0800
0x08002632 4002 DCW 0x4002
0x08002634 2000 DCW 0x2000
0x08002636 4001 DCW 0x4001
0x08002638 00BC DCW 0x00BC
0x0800263A 2000 DCW 0x2000
0x0800263C 6410 DCW 0x6410
0x0800263E 4002 DCW 0x4002
0x08002640 0C00 DCW 0x0C00
0x08002642 4002 DCW 0x4002
0x08002644 00AC DCW 0x00AC
0x08002646 2000 DCW 0x2000
0x08002648 0028 DCW 0x0028
0x0800264A 2000 DCW 0x2000
0x0800264C ED18 DCW 0xED18
0x0800264E E000 DCW 0xE000
0x08002650 E400 DCW 0xE400
0x08002652 E000 DCW 0xE000
0x08002654 680D DCW 0x680D
0x08002656 3B53 DCW 0x3B53
0x08002658 0054 DCW 0x0054
0x0800265A 2000 DCW 0x2000
0x0800265C 008C DCW 0x008C
0x0800265E 2000 DCW 0x2000
0x08002660 3830 DCW 0x3830
0x08002662 4002 DCW 0x4002
0x08002664 1000 DCW 0x1000
0x08002666 4002 DCW 0x4002
0x08002668 6425 DCW 0x6425
0x0800266A 0000 DCW 0x0000
0x0800266C 003C DCW 0x003C
0x0800266E 2000 DCW 0x2000
0x08002670 0090 DCW 0x0090
0x08002672 2000 DCW 0x2000
0x08002674 0046 DCW 0x0046
0x08002676 2000 DCW 0x2000
0x08002678 6F50 DCW 0x6F50
0x0800267A 797A DCW 0x797A
0x0800267C 6A63 DCW 0x6A63
0x0800267E 3A61 DCW 0x3A61
0x08002680 2520 DCW 0x2520
0x08002682 0073 DCW 0x0073
0x08002684 6E45 DCW 0x6E45
0x08002686 6F6B DCW 0x6F6B
0x08002688 6564 DCW 0x6564
0x0800268A 3A72 DCW 0x3A72
0x0800268C 2520 DCW 0x2520
0x0800268E 0073 DCW 0x0073
0x08002690 0038 DCW 0x0038
0x08002692 2000 DCW 0x2000
0x08002694 0050 DCW 0x0050
0x08002696 2000 DCW 0x2000
0x08002698 006C DCW 0x006C
0x0800269A 2000 DCW 0x2000
0x0800269C 006F DCW 0x006F
0x0800269E 2000 DCW 0x2000
0x080026A0 0072 DCW 0x0072
0x080026A2 2000 DCW 0x2000
0x080026A4 0075 DCW 0x0075
0x080026A6 2000 DCW 0x2000
0x080026A8 0078 DCW 0x0078
0x080026AA 2000 DCW 0x2000
0x080026AC 007B DCW 0x007B
0x080026AE 2000 DCW 0x2000
0x080026B0 0068 DCW 0x0068
0x080026B2 2000 DCW 0x2000
0x080026B4 F7FFFDB8 BL.W recalculate_val (0x08002228)
有人可以解释一下B,DCW(为什么这么多?)和BL.W指令的用途?
答案 0 :(得分:2)
B
指令是无条件分支,似乎分支到recalculate_val
例程的调用。 BL
指令是一个所谓的"分支,带有链接"并用于调用函数,以便指令指针可以在函数返回后返回BL
之后的指令。
DCW
指令定义内存的全局半字。您必须查找可能与这些数据相对应的全局初始化数据的任何定义。它们不是真正的指令,您可以看到左侧(它们的编码方式)与右侧(它们定义的数据)相同。
无论如何,您展示的代码片段并未包含recalculate_val
例程的定义。您必须查看地址0x08002228
(BL
跳转的地方)的内容。此外,编译器似乎并不尊重inline
说明符。
答案 1 :(得分:2)
对于B,DCW(为什么这么多?)和BL.W指令
B
是无条件跳转,BL
是函数调用(使用链接跳转)。
DCW
是常量。仔细看看它们:
0x08002620 006A DCW 0x006A
0x08002622 2000 DCW 0x2000
这是0x2000006A
,很可能是RAM中变量的地址。
0x08002624 0024 DCW 0x0024
0x08002626 2000 DCW 0x2000
这是0x20000024
,另一个RAM地址。
0x08002628 0C2C DCW 0x0C2C
0x0800262A 4000 DCW 0x4000
此0x40000C2C
位于外围空间 - 很可能是寄存器地址。
它们的原因是您无法直接在Thumb2指令中编码大多数32位值。一种解决方法是使用上面的表和指令
LDR Rx, [PC + y]
将相应的表值加载到目标寄存器中。
您应该在显示的代码上方或下方的反汇编中找到匹配的LDR
说明。
但是这条LDR
指令的范围有限 - 特别是当编码为16位时。这就是为什么编译器可以在某些代码的中间插入一个表并使用B
指令跳转它。