2.2.1 基本运算部件
在计算机中,运算器由算术逻辑单元(Arithmetic Logic Unit,ALU)、移位器、状态寄存器(PSW)和通用寄存器组等组成。运算器的基本功能包括加、减、乘、除四则运算,与、或、非、异或等逻辑运算,以及移位、求补等操作。ALU的核心部件是加法器。
1. 一位全加器
全加器(FA)是最基本的加法单元,有三个输入:加数 、加数 与来自低位的进位 ,两个输出:本位和 及向高位的进位 。其逻辑表达式如下。
和表达式: (当 、、 中有奇数个1时,,否则 )
进位表达式:
2. 串行进位加法器
将 个全加器级联可构成 位串行进位加法器(又称行波进位加法器),特点是进位信号逐级传递,每一级的进位输出直接作为下一级的进位输入。
在串行进位加法器中,总运算延迟主要由进位信号从最低位传播到最高位的时间决定。位数越多,进位链越长,延迟越大。因此,缩短进位传递路径是提升加法器性能的关键。
*3. 并行进位加法器
并行进位(也称先行进位)加法器能够显著提升加法运算速度,因为它能以几乎同时生成所有进位信号的方式工作,而非逐级传递进位。为了实现这一目标, 个一位全加器被连接至一个 位先行进位逻辑部件(CLA部件),以便几乎同时生成所有进位信号。因此,并行进位加法器对于较大位数的数据处理效率要高于串行进位加法器。
4. 带标志加法器
对于 位加法器来说,除了得到运算结果外,还要关注加法运算过程中是否发生了溢出、结果的正负性、结果是否为零等,这些信息对于程序的执行控制非常关键。为此,在 位加法器的基础上增加了额外的逻辑电路,不仅支持计算和/差,还能生成以下标志位:OF、CF、SF和ZF,每个标志占1位。
溢出标志OF通过检测最高有效位的进位输入 与进位输出 是否不同决定,即 ,用于判断有符号数加法运算是否溢出: 表示溢出, 表示未溢出。符号标志SF等于结果的最高有效位,即 ,用于指示有符号数加法运算结果的正负性: 表示结果为正, 表示结果为负。零标志ZF在结果的所有位均为0时设置为1,用于指示加减运算的结果是否为零: 表示结果为0, 表示结果非零。进位/借位标志CF用于判断无符号数的加减运算是否发生溢出: 表示溢出, 表示未溢出。
5. 算术逻辑单元(ALU)
是一种功能较强的组合逻辑电路,能够执行多种算术与逻辑运算。其中,加法和减法由带标志加法器直接完成;乘法和除法则通常通过ALU配合控制逻辑,以多次加减和移位的方式迭代实现。此外,ALU还能执行与、或、非等基本逻辑运算。A和B为两个 位操作数输入端, 为进位输入端,ALUop为操作控制信号,用于选择ALU执行的具体功能。例如,当ALUop选择加法(Add)时,ALU输出 。ALUop的位数决定了可支持的操作种类数量。例如,3位ALUop最多可支持8种不同操作。
2.2.2 定点数的移位运算
当计算机中没有乘/除运算电路时,可以通过加法和移位相结合的方法来实现乘/除运算。对于任意二进制整数,左移一位,若未发生溢出,相当于乘以2(类似于十进制数左移一位相当于乘以10);右移一位,若忽略因移出而舍去的末位尾数,相当于除以2。
根据操作数的类型不同,移位运算可以分为逻辑移位和算术移位。
1. 逻辑移位
逻辑移位将操作数视为无符号整数。逻辑移位的规则:左移时,高位移出,低位补0。若高位的1移出,则发生溢出。右移时,低位移出,高位补0。
例如,4位无符号数0001(+1)左移一位变为0010(+2),相当于乘以2,未溢出;0001(+1)右移一位变为0000(0),相当于除以2并舍弃小数部分。又如,1000(+8)左移一位变为0000(0),相当于乘以2,但结果超出了4位无符号数的表示范围,发生溢出。
2. 算术移位
算术移位需要考虑符号位的问题,即将操作数视为有符号整数。有符号整数采用补码表示,因此对于有符号整数的移位操作应采用补码算术移位方式。算术移位的规则:左移时,高位移出,低位补0。若移出的高位与原符号位不同(左移后符号位改变),则发生溢出。右移时,低位移出,高位补符号位。若低位的1移出,则影响精度。
例如,4位补码0010(+2)左移一位变为0100(+4),未溢出;1001(-7)左移一位变为0010,符号由负变正,表明发生溢出(因为-14超出了4位补码的表示范围)。又如,1001(-7)右移一位变为1100(-4),保留了符号位,但丢失了最低有效位,影响精度。
2.2.3 定点数的加减运算
1. 补码加减运算
补码加减运算规则简单,易于硬件实现。补码加减运算的公式如下(设字长为 )。
补码运算具有以下特点:
- 按二进制加法规则运算,逢二进一。
- 若做加法,则两个数的补码直接相加;若做减法,则将被减数与减数的负数补码相加。
- 符号位与数值位一同参与运算,结果符号位由运算自然得出。
- 运算结果自动截断为 位(模 运算),高位进位被丢弃。
【例2.3】 设字长为8位(含1位符号位),,,求 和 。
解:
,;求得 ,,。则:
符号位为0,真值为+39。
符号位为1,真值为-9。
2. 溢出判别方法
补码加减运算仅在同号相加或异号相减时可能发生溢出。例如,两个正数相加结果为负,或一个负数减去一个正数结果为正。常用的溢出判别方法有以下三种。
(1) 采用一位符号位
减法运算在机器中是用加法器实现的,因此加法和减法均可统一视为两个补码数相加。溢出仅发生在参与运算的两个数符号相同,而结果符号与之不同的情况下。设参与运算的两个操作数的符号位分别为 和 ,运算结果的符号为 ,则溢出逻辑表达式为
(2) 采用一位符号位并结合进位情况
设符号位(最高位)产生的进位为 ,最高数值位(次高位)产生的进位为 。若 与 不同,则表示溢出。溢出逻辑表达式为
(3) 采用双符号位
使用两个符号位 ( 为高位符号位),若两个符号位不同,则表示溢出。 的各种情况如下:
- :表示结果为正数,无溢出。
- :表示结果正溢出。
- :表示结果负溢出。
- :表示结果为负数,无溢出。
溢出逻辑表达式为
在上述三种方法中,若 ,则表示无溢出;若 ,则表示有溢出。
3. 加减运算电路
在计算机中,无论是无符号数还是有符号数的加减运算,均采用同一套硬件电路实现,即“一套电路,两种语义”。一个加减运算部件,其输入端包括两个 位操作数X和Y,以及一个控制信号Sub。其中,Y分成两路:一路直接接入二选一多路选择器(MUX),另一路经 位反相器后接入同一选择器。控制信号Sub不仅决定选择哪一路数据进入加法器,还在执行减法时作为最低位的进位输入。输出端包括 位运算结果F以及各类标志位。
(1) 加法运算的工作原理
无论是无符号数还是补码表示的有符号数,其加法均通过同一加法器电路完成。当执行加法操作时(Sub=0),电路实现过程如下。
输入:X直接接入加法器的一端;Y接入MUX。
控制信号:Sub=0,同时作为加法器的最低位进位输入 。
运算:MUX在Sub=0时选择Y直接通过,加法器执行 (),输出 位结果F和进位输出 ,并生成状态标志位。
语义解释:
-
若X、Y被视为无符号数,则结果 。当 时,产生进位 ,表示发生无符号溢出;此时,标志 反映进位状态。
-
若X、Y被视为有符号数(、),则结果 。此时,若两个操作数同号而结果异号(如正+正 负),则表示有符号溢出,由溢出标志OF指示。
(2) 减法运算的工作原理
无论是无符号数还是补码表示的有符号数,其减法也通过同一加法器电路实现。当执行减法操作时(Sub=1),电路实现过程如下:
输入:X直接接入加法器的一端;Y接入MUX。
控制信号:Sub=1,同时作为加法器的最低位进位输入 。
运算:MUX在Sub=1时选择反相后的 输出,加法器执行 (),输出 位结果F和进位输出 ,并生成状态标志位。
语义解释:
-
若X、Y被视为无符号数,则该运算等价于计算 (模 运算):
- 时,,有进位 ,舍去高位后 ,表示无借位(结果非负)。
- 时,,无进位 ,表示有借位(结果为负,超出 位无符号数范围),表示发生无符号溢出。此时,标志 反映借位状态。
-
若X、Y被视为有符号数 (、),则该运算等价于 :
- 结果F即为 。
- 若运算导致结果超出 位补码表示范围(例如,正减负得负,或负减正得正),则发生有符号溢出,由溢出标志OF指示。
NOTE运算器本身无法识别所处理的二进制串是有符号数还是无符号数。例如, 若解释为有符号数,对应值为-1,结果正确;若解释为无符号数,对应值为 ( 位无符号数的最大值),与数学结果不符。此类易混点是统考极易考查的内容。
(3) 各类标志位的含义
可通过状态标志位来区分有符号数与无符号数的运算结果,各类标志位的含义如下。
零标志ZF:当结果 时,;否则 。对有符号数和无符号数均有意义。
溢出标志OF:用于判断有符号数运算是否发生溢出, (符号位进位与最高数值位进位的异或)。对无符号数运算无意义。即无法依据OF判断无符号数运算是否溢出。例如,无符号加法010+011=101,虽然OF=1,但结果并未溢出。
符号标志SF:等于结果F的最高位(符号位)。仅对有符号数有意义。
进/借位标志CF:用于表示无符号数运算中的进位/借位情况,判断是否溢出。仅对无符号数有意义。加法(Sub=0)时,CF=1表示有进位,即发生上溢,。减法(Sub=1)时,CF=1表示有借位,即不够减,CF等于 反。综合得 。例如,无符号数加法110+011产生进位;无符号数减法000-111产生借位,结果均发生溢出(CF=1)。
(4) 无符号数大小的比较
在无符号数运算中,零标志ZF和进/借位标志CF是判断大小关系的关键。设A和B为两个无符号数,执行运算 后,根据ZF和CF的值可判断A和B的大小。
- 若 。如 ,结果为零 ,无借位 。
- 若 。如 ,结果非零 ,无借位 。
- 若 。如 ,结果非零 ,有借位 。
综上判断规则如下:当 时(无须检查CF),说明 ;当 且 时,说明 ;当 时(此时ZF必为0,无须额外检查),说明 。
(5) 有符号数大小的比较
在有符号数运算中,零标志ZF、溢出标志OF和符号标志SF共同用于判断大小关系。设A和B为两个有符号数,执行 ,根据ZF、OF和SF的值可判断A和B的大小。
- 若 。如 ,得 , , 。
- 若 。无溢出示例:,得 ,,;有溢出示例:,得 ,,。
- 若 。无溢出示例:,得 ,,;有溢出示例:,得 ,,。
综上,判断规则如下:当 时,说明 ;当 且 (或 ) 时,说明 ;当 且 (或 ) 时,说明 。
NOTE当 且未发生溢出时,即 时,若 ,则表示结果非负,说明 ;当发生溢出时,即 时,若 ,则必然是正数减去负数发生溢出导致结果为负,说明 。
当 且未发生溢出时,即 时,若 ,则表示结果为负,说明 ;当发生溢出时,即 时,若 ,则必然是负数减去正数发生溢出导致结果为正,说明 。
*4. 原码的加减运算(了解)
在原码加减运算中,需将符号位与数值位分开处理,规则较为复杂,具体如下。
加法规则:遵循“同号求和,异号求差”的原则,先判断两个操作数的符号。具体来说,若符号相同,则数值位相加,结果符号位不变,若数值位相加时最高位产生进位,则发生溢出;若符号不同,则用绝对值较大的数减去绝对值较小的数,结果符号位与绝对值较大的数相同。
减法规则:先将减数的符号取反,再将被减数与符号取反后的减数按原码加法进行运算。
2.2.4 定点数的乘除运算
1. 乘法运算
(1) 原码乘法的运算原理
原码乘法的特点是符号位与数值位分别处理,其运算过程分为两步:
- 乘积的符号位由两个乘数的符号位异或得到;
- 乘积的数值位是两个乘数绝对值的乘积。数值位的乘法可归结为两个无符号数的相乘。
可写成数学推导形式:
在硬件实现中,通常采用部分积右移的方式将上述求和过程转换为迭代形式。设乘数 (其中 为最低位),定义部分积序列 如下:
其中,“”表示逻辑右移一位。需要注意的是,这里的右移是位操作的一部分,而非数学上的除法;所有中间结果均在 位存储空间中保留完整精度。经过 次迭代后,最终得到的 位部分积 即为乘积 的完整二进制表示。因此,乘法运算可通过加法和移位实现。
为了保证精度,部分积需要使用 位寄存器存储。原码乘法的过程可归纳如下:
-
被乘数和乘数均取绝对值,作为无符号整数参与运算,结果的符号位为 。
-
初始化部分积 ,从乘数的最低位 开始,将当前部分积 加上 ,然后逻辑右移1位。重复此步骤 次,最终所得的 位部分积即为数值乘积。
(2) 无符号整数的乘法运算电路
一个32位无符号数乘法运算器的逻辑结构。该电路采用加法与移位相结合的方法来完成乘法运算,其设计思想源自手算乘法的基本原理。
下面介绍其主要组成部分及其工作原理。
- 初始化
- 被乘数寄存器X:存储32位被乘数X,在整个乘法过程中保持不变。
- 乘数寄存器Y:初始时存储32位乘数Y。
- 乘积寄存器P:初始化为0,用于存放累加的部分积(高32位结果)。
- 计数器 :初始化为n(本例为32),表示需进行n次迭代。
- 执行过程(循环n次)
- 判断:将乘数寄存器Y的最低位,送入控制逻辑。
- 加法操作:若Y的最低位为1,则将当前部分积P加上被乘数X,并将进位存入进位触发器C;若Y的最低位为0,则执行空操作。
- 移位操作:将C、P和Y视为一个整体,执行一次逻辑右移。具体来说,进位C移入P的最高位;P的最低位移入Y的最高位;Y的最低位被丢弃。
- 更新计数器:计数器 减1。若 ,则继续下一轮迭代,否则算法结束。
- 结果与溢出判断
- 最终结果:64位乘积结果存储在寄存器对 [P
] 中,其中P为高32位,Y为低32位。 - 溢出判断:若高32位结果P不为零,则表明乘积超出了32位无符号数的表示范围,发生溢出。此时,处理器将溢出标志OF与进位标志CF同时置1。
- 溢出处理
溢出处理属于软件层面的操作,通过检查CF或OF标志位即可判断是否发生溢出。若检测到溢出,则可在乘法指令后插入一条溢出自陷指令,自动触发异常处理程序,以处理错误(如报告错误、转为高精度计算等)。对于不要求结果精确性的应用,程序员可选择忽略溢出。
(3) 有符号整数的乘法运算电路
有符号整数采用补码表示,其乘法需要同时处理符号与数值。A.D.Booth提出的Booth算法让符号位与数值位统一参与运算,直接生成补码形式的乘积,且对正数和负数一视同仁。
需要说明的是,Booth算法的数学推导较为复杂,通常不在考研考查范围内,因此本书仅介绍其实现结构,不深入讨论其背后的原理。
下面介绍其主要组成部分及其工作原理。
- 初始化
- 被乘数寄存器X:存储32位被乘数,在整个乘法过程中保持不变。
- 乘积寄存器P:初始化为0,用于存放累加的部分积(高32位结果)。
- 乘数寄存器Y:初始时存储32位乘数;在其右侧附加一个辅助位 ,且初始化为0。
- 计数器 :初始化为n(本例为32),表示需要进行n次迭代。
- 执行过程(循环n次)
- 判断:将Y的最低位 与辅助位 组合形成两位二进制码,送入控制逻辑。
- 加减法:若组合为10,则执行 (减去被乘数);若为01,则执行 (加上被乘数);若为00或11,则执行空操作(Booth算法的原理请参见教材)。
- 移位:将P、Y和辅助位 视为一个整体,执行一次算术右移。具体来说,P的最低位移入Y的最高位;Y的最低位移入辅助位 ;原辅助位 被丢弃。
- 循环控制:计数器 减1。若 ,则继续下一轮迭代,否则算法结束。
- 结果与溢出判断
- 最终结果:64位乘积存储在寄存器对 [P
] 中,其中P为高32位,Y为低32位。 - 溢出判断:若高32位结果P不是低32位结果Y的符号扩展(P的所有位不等于Y的符号位),则判定为溢出。此时,处理器将溢出标志OF与进位标志CF同时置1。
- 溢出处理
其溢出处理同样由软件完成。执行有符号乘法指令(如imul)后,应检查OF标志位:若发生溢出,则可通过条件跳转进入错误处理程序,或者利用溢出自陷机制由硬件自动触发异常处理程序,以确保程序的健壮性;若已知操作数不会导致溢出,则也可选择忽略该标志。
(4) 乘法运算的三种实现方式
-
迭代式乘法器:即前文所述的经典实现结构,由ALU、移位器、寄存器和控制逻辑构成。通过多次迭代完成乘法,每次迭代处理一位乘数,若一次ALU运算和一次移位各需1个时钟周期,则完成 位乘法约需 个时钟周期。 -
阵列乘法器:一种全并行的快速乘法器。所有部分积同时生成,并以二维阵列形式组织,再通过加法器网络逐级压缩求和,从而直接得到最终乘积。由于整个数据通路为组合逻辑,在时钟周期足够长的前提下,可在单个时钟周期内完成一次乘法运算。 -
移位-加减法:利用移位与加法(或减法)的组合来模拟乘法运算(例如,乘以13可分解为 )。该方法的硬件成本最低,但运算速度最慢。
2. 除法运算
在进行定点数除法运算之前,需要先对被除数和除数的取值进行预判,以识别异常或确定结果是否为零。具体规则如下:
- 若被除数为0、除数不为0,或 被除数 除数 ,则商为0,余数等于被除数。
- 若被除数不为0、除数为0,则发生“除数为0”异常。
- 若被除数和除数均为0,则发生除法错误异常。
仅当被除数和除数均不为0且 被除数 除数 时,才进入正式的除法计算过程。
(1) 无符号整数的除法运算原理
无符号整数除法与乘法类似,也是一种基于移位与加减的迭代过程,但流程更为复杂。
在手算二进制除法中,为便于从最高位开始逐位试商,通常按固定位宽书写被除数,并在高位补0(例如将4位的1111写成00001111),这些前导零不改变数值大小。具体步骤如下:
- 取被除数的高 位部分(与除数同宽)作为初始部分被除数,与除数相减。若够减,则上商1,并将差值作为中间余数;若不够减,则上商0,中间余数即为该部分被除数。
- 将被除数的下一位“带下来”,拼接到当前余数末尾,形成新的 位部分被除数;再与除数相减,确定下一位商。如此重复,直到所有位处理完毕。
手算中在被除数前补0主要是为了便于对齐和观察;硬件设计采用类似的策略,将 位被除数高位补0扩展为 位,以支持统一的迭代过程。
(2) 无符号整数的除法运算电路
为了适应逐位试商的迭代过程,需要将被除数加载到一个64位寄存器中(高32位为0,低32位为实际被除数)。一般而言, 位无符号数除法采用一个 位的被除数(高位补0)除以一个 位的除数,产生 位的商和 位的余数。
下面介绍其主要组成部分及其工作原理。
- 初始化
- 除数寄存器Y:存储 位除数,在整个除法过程中保持不变。
- 余数/商寄存器Q:初始时存储 位被除数;在迭代过程中逐步生成 位商。
- 余数寄存器R:初始化为0,用于暂存中间余数。
- 计数器 :初始化为n,表示需要执行n轮迭代。
- 异常预检:若除数为0,则立即触发“除零错误”异常,停止除法运算;若被除数 除数,则商=0,余数=被除数,无须进入执行过程。
-
执行过程(循环n次)
- 移位:将R与Q视为一个整体,执行一次逻辑左移。具体来说,R的最高位被移出(通常丢弃),Q的最高位移入R的最低位,Q的最低位空出以接收新商位。
- 试商与减法:计算 ;若结果大于或等于0,则当前商位为1,并将结果(差值)写回R;若结果小于0,则当前商位为0,并执行 以恢复余数(撤销减法)。
- 循环控制:计数器 减1。若 ,则继续下一轮迭代,否则算法结束。
-
最终结果
最终的 位商存储在寄存器Q中, 位余数存储在寄存器R中。
- 异常处理
当检测到“除数为0”时,除法器立即停止运算,并置位“除零”异常标志。该异常通常由硬件自动捕获,并通过中断向量表跳转至预设的异常处理程序。
NOTE两个 位无符号数相除不会发生溢出。因为被除数最大为 ,最小的非零除数为1,此时商为最大值,即为 ,恰好可用 位无符号数表示。
(3) 补码除法运算的工作原理
补码作为有符号整数的标准表示形式,其除法运算需要同时处理符号与数值。补码除法让符号位与数值位统一参与运算,商的符号在运算过程中自然生成。对于两个 位补码数相除,被除数需要先进行符号扩展至 位;若被除数为 位,除数为 位,则无须扩展。
由于补码除法涉及有符号数的比较、加减和移位,其试商规则要比无符号除法复杂得多。根据考试大纲要求,仅需掌握其基本实现,底层的原理可参见教材。补码除法的硬件结构与无符号除法电路基本一致,下面结合该图说明其基本工作过程。
- 初始化:
- 除数寄存器Y:存储 位除数,在整个除法过程中保持不变。
- 余数/商寄存器Q:初始时存储 位被除数;在迭代过程中逐步生成 位商。
- 余数寄存器R:所有位都初始化为被除数的符号位,即完成符号扩展。
- **计数器 **:初始化为n,表示需要执行n轮迭代。
- 异常预检:若除数为0,则立即触发“除零错误”异常,停止除法运算;若 被除数 除数 ,则商=0,余数=被除数,无须进入执行过程。
-
执行过程(循环n次)
- 移位:将R与Q视为一个整体,执行一次算术左移。
- 试商与加减:控制逻辑根据 与 的关系,发出加法或减法信号以确定当前商位。由于涉及有符号数的恢复机制,具体判定规则较复杂,此处不展开。
- 循环控制:计数器 减1。若 ,则继续下一轮迭代,否则算法结束。
-
最终结果
最终的商存储在Q中,余数(符号与被除数相同)存储在R中。
- 异常处理
当检测到除数为0或发生商溢出时,除法器立即停止运算,并置位相应异常标志,该异常的捕获和处理方式与无符号除法类似。值得注意的是,在两个 位补码除法中,商溢出仅有一种情形 被除数为最大负数 ,且除数为-1,此时结果 无法用 位补码表示。