【问题标题】:Conditional Jump instructions?条件跳转指令?
【发布时间】:2009-10-11 20:53:41
【问题描述】:

参加编译器设计课程:

条件跳转指令是什么意思?我是基于 C/C++ 的程序员,因此如果该范例中有任何代码示例,您可以分享以帮助我更好地理解这一点。

无限条件跳转指令是什么意思?

书中陈述的一个例子:

许多处理器都有条件跳转 仅用于有条件的说明 以有限的范围跳跃。为了 例如,跳跃的目标可能 不超过 128 字节 从当前程序计数器。 有时,这样的汇编程序 处理器仍然允许无限 条件跳转。

我是否必须了解汇编程序才能理解这一点?

我希望提供参考资料的链接以供进一步阅读。

【问题讨论】:

  • 我想说,至少了解基本的汇编语言是编译器设计课程的先决条件。我并不是说这话是刻薄的,只是说你将需要为学习汇编语言付出一些努力。
  • “我希望提供参考资料的链接以供进一步阅读。”谷歌递归下降解析器,将残酷的 asm 东西保存起来,以便在几天后工作。 Google q=Tiny 只筛选那些看起来像编译器的响应。谷歌还有:大卫·埃克

标签: compiler-construction cpu


【解决方案1】:

许多处理器都有条件跳转指令,仅用于有限范围的条件跳转。例如,跳转的目标距离当前程序计数器可能不超过 128 字节。

以 x86 条件跳转为例,例如 JNZ,这意味着“如果处理器的零标志未设置则跳转”(processor flags 将由之前的算术运算设置或清除)。

JNZ 操作码有一个操作数,它表示跳多远。对于JNZ 操作码,操作数使用单个字节进行编码(即只有操作码之后的第一个字节被解释为操作数;下一个字节是下一个操作码的开始),因此它可以指定不再跳转大于或等于 128 个字节。

[它使用短的 1 字节操作数,因为短跳转是最常见的情况,这种针对最常见情况的优化有助于使整体代码更小]。

有时,这种处理器的汇编器仍然允许无限的条件跳转。

这意味着当您在高级汇编中编写时,您可以编写...

jnz distant_label
[other instructions]
distant_label:

...即使距离标签超过 128 个字节。当 CPU 本身只支持短的条件跳转时,它怎么能做到这一点?可能是因为汇编器(像编译器一样“组装”你的汇编语言)会自动插入一些额外的必要操作码,因此最终发出的内容类似于 ...

jz nearby_label
jmp distant_label
nearby_label:
[other instructions]
distant_label:

...在哪里:

  • jmp distant_label 不是 jnz distant_label 而是 JMP 是无条件跳转,它的操作数更大,可以无限跳转距离
  • 而不是 jnz distant_label 有 jz nearby_label - 'JNZ' 被 'JZ' 替换,这意味着不是“如果标志不为零则跳转到远处标签”,而是“跳转到附近的标签,所以不要” t 跳远,如果标志为零”(这最终的含义与您所写的相同,因为“如果不为零则跳转”与“如果为零则不跳转”的含义相同)。

【讨论】:

  • 我对优化很感兴趣。读完这篇文章后,我想知道跳跃的距离会在多大程度上影响速度。
【解决方案2】:

我认为这解决了您的问题:例如,在 Microchip PIC18F 系列中,您有一个bra(分支)命令和一个goto 命令。它们实际上是相同的,但不同之处在于bra 命令只能从其位置跳转到-1024 到+1023 个字的位置,并且它只使用程序存储器的一个字。 goto 命令可以跳转到程序内存中的任何地方,但它需要两个字的程序内存才能允许跳转到任何地方。

如果你错误地尝试分支到一个太远的标签,编译器会给你一个错误。

当然,当您只有 2K 字的程序存储器时,这些额外的字会产生影响。

bra 和 goto 本身是无条件跳转;但是,有几个条件分支命令,例如bc(进位分支)、bz(零分支)、bnz(非零分支)等,它们都从最后一个开始检查状态寄存器(算术)运算,仅当指定条件为真时才执行分支。

如果你需要一个条件goto,那么你会有类似的东西

DELAY
    nop
    nop
    decfsnz DelayCount
    goto DONE_WITH_DELAY
    bra DELAY

我们执行两个无操作以“睡眠”片刻;递减一个名为DelayCount的“变量”,如果DelayCount为零,那么我们无条件跳转到标记为DONE_WITH_DELAY的代码;如果它不为零,我们跳回到DELAY 标签并再次执行此操作。 (decfsnz 表示“递减f,如果不为零则跳过)

【讨论】:

    【解决方案3】:

    关于条件分支,你可以从这个定义开始:

    Branch (computer science):

    有两种常用的分支形式 指令:条件分支 可以采取或不采取, 取决于 CPU 等条件 标志和无条件分支 总是被占用。

    if, for, while C 语句被编译为条件跳转汇编运算符。而goto 语句编译为无条件跳转运算符。

    关于跳转的有限/无限范围:范围是跳转指令的地址和跳转到的地址在内存中的“距离”。维基百科中的Program counter 文章可以为您提供有关此问题的更多信息。

    您不必了解汇编程序就可以理解这些主题,但我建议您学习 CPU 架构的基础知识。

    【讨论】:

    • 对不起,我的意思是无限条件跳转
    • 是的,我设法收集了 IA-32 的全部三卷作品 - 有点像以前在公开论坛上回答第一天问题后的顽固战争留下的伤痕。我们可以建议惠普手机计算器作为一个更好的初学者地方吗?这将回答 op 的原始问题。很想要求 op 在 8 位 Tiny 中实现有限自动机。 (我是扭曲还是什么?)
    【解决方案4】:

    条件跳转会在逻辑上转换这个 if 语句:

    if(a == b)
    {
      // do something
    }
    
    // do something else
    

    进入这个:

    if(!(a==b)) goto somethingElse;
    // do something
    
    somethingElse:
    // do something else
    

    if(!(a==b)) 行将变成汇编命令:

    CMP A, B
    JNE somethingElse
    

    现在,至于“无限条件跳转”,我认为它们的意思是远跳?

    【讨论】:

    • -1 这个答案毫无意义。条件跳转不会将任何东西变成其他任何东西。
    【解决方案5】:

    条件跳转就像

    if (condition) goto
    

    在 C 中。无条件跳转就像

    goto
    

    在 C 中。

    我不知道“无限”是什么意思。它可能特定于正在讨论的特定处理器。

    【讨论】:

      【解决方案6】:

      简而言之:

      条件意味着类似

      if(condition)
      {
        //condition met
      }
      else
      {
        //condition no met
      }
      

      这意味着程序流程会根据条件表达式而改变。

      无条件跳转是 goto 语句或函数调用的典型编译器实现。

      【讨论】:

        猜你喜欢
        • 2019-09-12
        • 2014-11-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-24
        • 1970-01-01
        • 2012-06-14
        相关资源
        最近更新 更多