【问题标题】:why we need a flag to indicate zero result?为什么我们需要一个标志来指示零结果?
【发布时间】:2019-03-20 07:18:42
【问题描述】:

shift、add、increment 等指令中,我们总是检查结果,如果结果为零,我们会在标志中指出。 在什么情况下我们使用这个零标志? 这个零标志有什么用?

【问题讨论】:

标签: assembly cpu-registers flags zero


【解决方案1】:

我们将这些标志用于两个主要目的:

  • 代码的条件执行(如果这些标志之一设置为特定值,通常会有分支/跳转指令转移执行),这包括循环,而不仅仅是高级语言中的 if/then/else 语句
  • 复杂的算术和按位逻辑,包括任意精度算术(其中携带在很长整数的寄存器大小部分的加法/减法/移位之间传播)

并非所有 CPU 都具有以零、负数、无符号上溢/下溢(或进位/借位)、有符号上溢、奇偶校验等方式描述 ALU 操作结果的标志。

MIPS CPU 没有用于整数和位运算的此类标志。有条件分支,可以在以下条件下分支:

  • 注册平等/不平等
  • 将相等性注册为零/非零
  • 寄存器小于/大于零
  • 寄存器大于/小于或等于零

如果需要这些分支不支持的不同类型的比较,则有专门的说明。他们将结果设置为 0 或 1,然后条件分支可以将其用作输入。

进位和溢出在 MIPS 处理器上有点棘手。需要通过多条指令获取。

【讨论】:

    【解决方案2】:

    通常,CPU 的标志用于执行条件操作。

    (一个例外是进位标志,它既用于条件运算,也用于“进位”,如加法进位或减法借位。)

    在 ARM CPU 上,您可以执行基于零标志的任何指令:例如,如果设置了零标志,指令 ldmeqda 将与指令 ldmda 执行相同的操作;当零标志被清除时,它不会做任何事情。

    通常您首先执行减法(使用cmp 指令)以比较两个数字。如果两个数字相等,则设置零标志。仅当两个数字不相等时才执行下一条指令,因此您根据零标志的状态执行指令。

    (cmp 指令执行减法并丢弃结果!这意味着该指令仅根据减法的结果设置标志。这在 C 时很有用oMP有两个数字;这就是指令被命名为cmp的原因。)

    在大多数其他具有标志的 CPU(并非所有 CPU 都有标志)上,您只能根据标志的状态进行跳转(分支)。

    如果标志状态错误,则跳过不执行的指令。

    示例(x86):

    someloop:
        mov eax, [esi]
        add esi, 20
        add eax, 1234
        # The zero flag will be set if the result is 0
        # The next instruction will jump if the zero flag is set
        jz skipif
        # We only get here if the zero flag is clear
        # This corresponds to "if(eax!=0)" in C
        mov [esi-10],bl
    skipif:
        dec edx
        # The zero flag is set if edx is not 0
        # Jump back to "someloop" if this is the case
        # This corresponds to a "do { ... } while((--edx)!=0);"
        # loop in C
        jnz someloop
    

    【讨论】:

      猜你喜欢
      • 2023-03-14
      • 2014-10-05
      • 1970-01-01
      • 1970-01-01
      • 2012-04-02
      • 2011-08-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多