8

我最近参加了一门数字逻辑课程,并了解了 AND、OR 和各种其他类型的逻辑。我们没有涉及的一件事是if语句,这对编程来说是完全必要的,它让我对它们的工作方式感到好奇。

我最好的猜测是它只是一个 2:1 多路复用器,当你添加更多else语句时,它会变成 4:1 和 8:1,但这对于这样一个简单的概念来说似乎有点太复杂了。

有谁知道一个if语句实际上翻译成什么?

4

7 回答 7

1

If 语句和所有其他控制流语句在逻辑级别实现为条件跳转。

当您使用 if 语句时,如下所示:

int a = 1, b = 0
if (a > b)
{
    ...

显然,任何智能编译器都会对此进行优化。如果我们特别指示我们的编译器尽可能地愚蠢并逐字生成指令,我们将得到如下内容:

my_if_statement:
    CMP   eax, ebx    # intrinsically works by subtracting ebx from eax
                      # eax and ebx are not changed, but the arithmetic flags are

                      # if it was greater, jump to greater label
    JG    my_if_statement_was_true

                      # if it wasn't greater, we get here
my_if_statement_was_false:
                      # do something
                      # we're now done, so jump to the end of the statement
    J     my_if_statement_end

my_if_statement_was_true:
                      # do something else
                      # now we're done with the if statement
my_if_statement_end:
                      # program continues

这些是汇编指令,每个指令都(大致)直接转换为机器码操作码。处理器做了很多额外的事情来支持加载和获取指令的过程,这在此处是相关的。有一个特殊的寄存器称为程序计数器(后面称为 PC 寄存器),它跟踪处理器将要执行的下一个操作码的位置。

  1. 首先,CMP 指令从第一个操作数中减去第二个操作数,并丢弃结果。但是,FLAGS 寄存器会使用算术运算的结果进行更新。
  2. 然后,JG 指令检查 FLAGS 寄存器中的 GREATER 标志是否设置。由于它在我们的示例中(回想一下 1 > 0),因此它执行跳转。
  3. 跳转指令会修改程序计数器 (PC),它是控制 CPU 从何处读取下一条指令的寄存器。
  4. CPU 然后尝试读取下一条指令。由于我们已经跳转,下一条指令不是紧跟在先前处理的指令之后的指令。

这是过程的概述。如果你想要更深入的解释,我建议你用 if 语句编写一个简单的 C 程序,编译它,反汇编它(使用 linuxobjdump或等效的),也许附加一个调试器并运行它。

linuxobjdump手册

要显示要在 中执行的下一条指令gdb,请使用display/i $pc

于 2013-06-24T19:15:58.707 回答
1

您忘记了程序是作为单独的指令执行的,并且(至少在最简单的情况下)指令是按顺序执行的。

因此,if (a + 4 > 5)一条指令将加载a到寄存器中,另一条指令将添加4,另一条指令将总和与 进行比较5。然后一条指令将从比较中测试“条件代码”,并执行紧随其后的指令(执行“if主体”)或“跳转”到内存中几个(或几十个)指令之外的位置(跳过“if主体” ”)。

那里有数字逻辑,但它处于较低级别,决定如何执行每条指令。

于 2013-06-24T18:55:45.547 回答
1

正确的if语句可以转换为比晶体管逻辑更高级别的东西。if语句通常被实现为条件分支(假设没有优化),或者将程序计数器增加默认数量,或者根据条件评估为真或假(通常为 1 或 0)将其设置为分支中指定的值。

于 2013-06-24T18:55:52.763 回答
1

自从我参加计算机体系结构课程以来已经有一段时间了,如果我对这个答案有点含糊,请原谅我。

您的计算机执行的所有指令都来自指令内存,我相信有一个数字代表要执行的指令的地址。

典型的指令有多个部分,1 个用于命令代码,通常部分用于最多 2 个源寄存器、目标寄存器和其他一些我 4 年多来不必考虑的东西。

无论如何,其中一个命令代码通常是条件跳转,如果您能理解您的数据路径如何在常规 ram 中存储/检索值,那么扩展该逻辑以将指令地址修改为文字值,或存储在特定寄存器中的值,基于另一个文字值/寄存器值是否等于 0

在此处输入图像描述

于 2013-06-24T19:01:08.430 回答
1

如果您只关心实现 if 条件,那么它很简单,

您可能已经阅读过 Morris Mano 的数字设计,其中给出了一个用于比较两个寄存器的简单电路,顺便说一下,如果您考虑一下,逻辑很简单。

a>b OR a<b OR a==b all these 3 instructions can be implemented easily
    by just comparing the two registers

现在,如果您关心 if 语句是如何在CPU中实现的,那么它会经历Fetch、Decode 和 Execute的 3 步循环。

之后,如前所述比较寄存器。

希望能帮助到你.. :)

于 2014-02-05T15:29:43.767 回答
0

if是编程语言中的控制流操作,而不是可以用数字逻辑表达的概念。如果您的课程涵盖了与汇编指令相关的机器jump(我不确定我是否曾经学过),那么这就是if陈述的内容。

于 2013-06-24T18:58:12.977 回答
0

正如上面其他人所说,有最终做出这些决定的逻辑比较器。根据设计需求(功率、面积、摆幅、时钟与否等),比较器有很多不同的实现方式。比较器由多个 CMOS NMOS/CMOS 门组成。

在维基百科页面上查看比较器,并查看动态锁存比较器。不幸的是,我没有足够的代表来发布一个。

这是一个动态锁存比较器的例子。根据实现是高电平有效还是低电平有效,系统将在此处对架构进行计时,以比较两个值并评估语句。

于 2013-06-24T18:59:41.727 回答