运算电路

数据表示

⭐ 中优先级

其实按照长时间线来看,运算电路直接考察得倒不多,但是这两年有考察增多的趋势,所以标记为中优先级。

加法运算电路

半加器

最基本的加法单元是 半加器 (Half Adder)。它有两个输入,一个是加数,一个是被加数,并有两个输出,一个是和,一个是进位。

如上图所示,通过对两个输入(A 和 B)进行 异或 (XOR)计算,可以得到 (S)。
通过对两个输入进行 (AND)操作,可以得到 进位 (C,即 Carry)。

半加器 的主要限制是它只能对两个位进行加法,并且不能处理来自低位的进位输入。

全加器

全加器 (Full Adder)是 半加器 的扩展,它加上了前一位的 进位 (Cin)作为第三个输入,并有两个输出,一个是 (S),一个是 进位 (C)。

半加器 用于处理两个位的简单加法,而 全加器 则可以处理包括 进位 在内的三位加法,是构建复杂加法电路的基础。

加法器

为了进行多位数的加法,全加器 可以串联起来形成一个 加法器 ,以处理多个位的二进制数加法。在这种安排中,每个 全加器进位输出 连接到下一个 全加器进位输入 。这样,一个 n 位的 加法器 可以通过串联 n 个 全加器 来实现。

上述 加法器 既可以处理 无符号加法 (unisnged),也可以处理 有符号加法 (int),因为二进制加法与数据类型无关,从 加法器 来说,只是对 0 和 1 进行操作,数据类型是对于二进制的解释方式。

一般而言,对于 有符号加法 ,加法器还需要考虑 标志位 ,所以加法器也被扩展为如下结构:

值得一提的是带符号加法器电路是如何输出各个 标志位 的,简单而言,每个 标志位 都可以通过 加法器 电路中的位信息组合得到。

  • ZF (zero flag):当 A+B 的结果中的每一位都为 0 时,ZF1 ,所以 ZF=!(F0​F1​⋯Fn−1​) 。

  • SF (signed flag):A+B 的结果的正负取决于输出结果的最高位,所以 SF=Fn−1​ 。

  • CF (carry flag):

  • 对于 加法 ,进位即最高位, CF=Cout​

  • 对于 减法 , CF=¬Cout​

    • OF (overflow flag): OF=Cn−1​⊕Cout​ ,
  • 如果 Cn−1​ 和 Cout​ 不同,则表示 符号位 的变化导致溢出,即:

    • 一个正数加上另一个正数,结果是负数。
    • 一个负数加上另一个负数,结果是正数。
  • 如果 CinCout 相同,则没有溢出发生。

减法运算电路

计算机中没有专门的减法电路,因为 补码减法 可以被转换为 加法 操作:

[A−B]补​=A补​+(−B)补​

以下电路可以实现操作数 A 和操作数 B加减法

如果是计算 A+B 的话,将 Sub 设置为 0,直接对 AB 进行 加法 计算。

如果是计算 A-B 的话,将 Sub 设置为 1,会对 B 进行取反加一,得到 −B补​=B补​​+1 ,然后使用 加法器 计算 A + (-B) 即可。

乘法运算电路

二进制乘法 与十进制乘法的手工计算方式类似:

1011 (this is binary for decimal 11) × 1110 (this is binary for decimal 14) ====== 0000 (this is 1011 × 0) 1011 (this is 1011 × 1, shifted one position to the left) 1011 (this is 1011 × 1, shifted two positions to the left)

  • 1011 (this is 1011 × 1, shifted three positions to the left) ========= 10011010 (this is binary for decimal 154)

在计算机中实现 乘法指令 可以通过如下几种方式模拟以上过程:

软件算法

如果没有专有硬件支持,可以通过一系列 加法位移 操作来实现 乘法 。编译器将 乘法运算 转换为一个循环代码段,在循环代码段中通过比较、加法 和移位等指令实现 乘法运算

// 如何使用加法和位移来实现两个整数的乘法(了解即可)
unsigned int multiply(unsigned int a, unsigned int b) {
    unsigned int result = 0;  // 结果初始化为 0
    while (b > 0) {           // 当第二个操作数大于 0 时继续循环
        if (b & 1) {          // 检查 b 的最低位是否为 1
            result += a;      // 如果是,将 a 加到结果上
        a <<= 1;              // 将 a 左移一位,相当于 a 乘以 2
        b >>= 1;              // 将 b 右移一位,去掉已经处理过的最低位
    return result;            // 返回计算的乘积

顺序乘法器

通过硬件的方式串行地模拟手工计算的方式,无符号数的 乘法硬件电路 如下图所示(了解即可):

其思路是通过 右移加法 ,每次输出 乘法结果 中的一位,由于原理稍复杂,这里不阐述更多细节。

阵列乘法器

阵列乘法器 (Array Multiplier)是一种用于执行 乘法运算 的硬件电路,它通过布置一系列 全加器半加器 在一个二维网格或阵列中来实现,它能够并行处理多个位的 乘法累加 ,可以在一个或多个时钟周期内完成 乘法操作

除法运算电路

二进制 除法 在计算机中的实现与我们在十进制中所执行的传统 除法 类似。

      00111    = 0111 = 7
     ----------
0010 | 00001111   被除数 X = 15 = 1111 = 00001111
         0010     除数 Y = 2 = 0010
         -----
          0011
          0010
          -----
           0011
           0010
           ----
           0001   余数 = 0001 = 1

二进制 除法 可以被总结为如下步骤:

  1. 准备
  • 将被除数和除数都转换为二进制形式。
  • 写下被除数和除数,类似于十进制除法的长除法形式。
  1. 除法
  • 从被除数的最高位开始,与除数进行比较。
  • 如果被除数当前部分大于或等于除数,则商为 1,否则商为 0。
  • 如果商为 1,则将被除数当前部分减去除数,并将差写在下面。
  • 将被除数的下一位数字移下来,与差组成新的被除数部分。
  • 重复上述步骤,直到被除数的每一位都被处理完毕。
  1. 余数
  • 最后一次减法运算得到的差即为余数。
  • 如果最后一次减法得到的差是 0,则表示整除,没有余数。

简单的 除法电路 结构也是通过模拟以上过程实现(了解即可):

除法电路 中,在每次迭代中我们将当前 余数 左移一位,并引入 被除数 的下一位,然后执行 余数减去除数 的操作,接下来通过条件判断检测 减法结果 的符号以确定 的当前位。

在每次迭代中,我们可以输出 除法结果 中的一位,重复直到处理完所有位后,可以得到 余数 的结果。

相关笔记

  • 概论
  • 计算机性能指标
  • 计算机系统层次结构