为什么 "guarded do" 在 asm 中优于 "jump to middle"

why "guarded do" is better than "jump to middle" in asm

我正在阅读一本教科书,其中描述了将 while 循环转换为机器代码的两种方法:

//jump to middle
   goto test;
loop:
   body-statement
test:
   t = test-expr;
   if (t)
       goto loop;

//guarded do

t = test-expr;
if (!t)
   goto done;
loop:
   body-statement
   t = test-expr;
   if (t)
      goto loop;
done:

不知道为什么使用第二种方法,编译器可以优化初始测试?

I don't know why using the secoond aproach, the compiler can optimize the initial test?

这就是 asm/机器代码的样子编译器完成后,使用 C 作为 asm 的伪代码. (这样写 C 是没有用的。)在我们到达这一步之后没有进一步的优化/编译发生。

在实际的 C 中,您只需像普通人一样编写 while(t)for(int i=0 ; i<n ; i++)(惯用的 C 循环),然后让编译器创建惯用的 asm 循环(底部的条件分支).这就是编译器的用途。

相关:

跳入中间的主要缺点是它在通过函数的所有路径上放置了一个额外的无条件跳转。 (循环是否运行零次迭代)。

剥离第一次迭代之前的测试以进行 if(run_at_all) do_loop 通过复制测试代码避免跳转,而不是跳转到它的单个副本。

有时它可以被优化掉:许多循环都有一个已知的行程计数,或者至少已知非零,如果编译器可以证明关于第一次迭代的t