在嵌入式编程讲座的this部分,Samek博士解释了编译器如何能够实现“原始代码”的效率(可能是由于这意味着由语法的逻辑顺序决定的实现) ):
我希望你注意到了 反汇编代码实现了不同的控制流 我为while循环描述的内容。假设原始代码 首先测试条件,然后跳过循环体,如果 条件不正确。编译后的代码以无条件开头 分支并反转循环体的顺序和测试 条件。但是,当你想到它时,那两个控制流程 是相同的,除了生成的更快,因为它只有 循环底部的一个条件分支。
在他的解释中,他参考了所示的两个流程图。描述编译代码的图表说明了“它在循环底部只有一个条件分支”。我似乎无法看到它在实践中如何运作:
0x2815 CMP
- > 0x1c40 ADDS
- > repeat until condition is false
0x2815 CMP
- > 0xdbfc BLT.N
- > 0x1c40 ADDS
- > repeat until condition is false
我可以理解两个控制流是如何相等的(至少从图中看是如此),但肯定不生成的(右边)如何更快。首先,两个图表最开始的箭头导致了相同的分支。其次,虽然分支似乎确实发生在右侧的原理图中,正如您从屏幕截图中看到的那样,模拟器似乎表明两个方法都是从机器指令开始的。比较(0x2815 CMP
)。
如何协调流程图与我在实践中看到的内容?
答案 0 :(得分:6)
我同意Kerren SB的回答。我将更详细地讨论它:
原始逻辑具有以下在每次迭代期间执行的跳转指令:
begin_loop:
cmp counter, 21
jge end_loop ; jump when greater or equal
...
jmp begin_loop
end_loop:
....
修订后的逻辑在每次迭代期间执行的指令减少一个:
jmp test_loop ; executed once; not part of loop
begin_loop:
...
test_loop:
cmp counter, 21
jlt begin_loop ; jump when less than
...
因此在循环中保存了无条件jmp begin_loop
。
答案 1 :(得分:5)
重要的唯一指令是在每个循环中重复的指令。重新排列逻辑的重点是每轮循环只有一个跳。在整个循环之前和之后可能会有几次跳跃,但我们并不关心这些。唯一昂贵的是那些一遍又一遍地完成的事情。