【问题标题】:Unnecessary ASM code不必要的 ASM 代码
【发布时间】:2014-10-24 11:19:59
【问题描述】:

我正准备为 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 指令都使用了什么?

【问题讨论】:

  • 你知道你的函数真的坏了吗?添加到未初始化的变量似乎不是一个好主意...至于您的问题,您显示的代码很可能是内存中的某个数组,可能带有寄存器或内存位置。
  • 你没有向我们展示你的程序,例如这个asm和C代码没有任何关系。

标签: c assembly arm keil


【解决方案1】:

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

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

无论如何,您显示的这段代码不包括recalculate_val 例程的定义。您必须查看地址 0x08002228 上的内容(BL 跳转的地方)。此外,编译器似乎不支持 inline 说明符。

【讨论】:

    【解决方案2】:

    对于B、DCW(为什么这么多?)和BL.W指令

    B是无条件跳转,BL是函数调用(带链接跳转)。

    DCWs 是常量。仔细观察它们:

    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 指令来跳过它。

    【讨论】:

      猜你喜欢
      • 2020-03-29
      • 2015-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-14
      • 2013-09-05
      • 2010-11-25
      • 2010-11-02
      相关资源
      最近更新 更多