不必要的ASM代码

时间:2014-10-24 11:20:00

标签: c assembly arm keil

我准备为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指令的用途?

2 个答案:

答案 0 :(得分:2)

B指令是无条件分支,似乎分支到recalculate_val例程的调用。 BL指令是一个所谓的"分支,带有链接"并用于调用函数,以便指令指针可以在函数返回后返回BL之后的指令。

DCW指令定义内存的全局半字。您必须查找可能与这些数据相对应的全局初始化数据的任何定义。它们不是真正的指令,您可以看到左侧(它们的编码方式)与右侧(它们定义的数据)相同。

无论如何,您展示的代码片段并未包含recalculate_val例程的定义。您必须查看地址0x08002228BL跳转的地方)的内容。此外,编译器似乎并不尊重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指令跳转它。