第三章 算术运算
3.1 引言
引入:实数如何表示,操作生成无法表示的大数如何处理,真正的乘除法?
- 实数的表示方法
- 算术的算法
- 实现算法的硬件
汇编标志位 名称 解释 CF 进位标志位 无符号运算中记录运算结果的最高有效位向更高位的进位值或从更高位借位,产生进位或借位时 C F = 1 CF=1 CF=1,否则 C F = 0 CF=0 CF=0 OF 溢出标志位 记录有符号运算结果是否发生了溢出,如果发生溢出 O F = 1 OF=1 OF=1,如果没有 O F = 0 OF=0 OF=0 PF 奇偶标志位 相关指令执行后结果所有bit中 1 1 1的个数为偶数 P F = 1 PF=1 PF=1, 1 1 1的个数为奇数则 P F = 0 PF=0 PF=0 SF 符号标志位 相关指令执行后结果为负那么 S F = 1 SF=1 SF=1,结果非负数则 S F = 0 SF=0 SF=0 AF:辅助进位标志位。运算过程中看最后四位,不论长度为多少。最后四位向前有进位或者借位,AF=1,否则AF=0;
ZF:零标志位。相关指令执行后结果为0那么ZF=1,结果不为0则ZF=0;
TF:调试标志位。当TF=1时,处理器每次只执行一条指令,即单步执行;
IF:中断允许标志位。它用来控制8086是否允许接收外部中断请求。若IF=1,8086能响应外部中断,反之则屏蔽外部中断;
DF:方向标志位。在串处理指令中,每次操作后,如果DF=0,si、di递增,如果DF=1,si、di递减;注意此处DF的值是由程序员进行设定的 cld命令是将DF设置为0,std命令是将DF设置为1;
3.2 加法和减法 Addition & Subtraction
-
加减法:进位与借位。(减法可以加上相反数的补码)
-
(补码)溢出:符号位被数值位占用
补码是带符号数的一种
-
不溢出:加法符号相异,减法符号相同
-
溢出:正+正=负,正-负=负,负-正=正
操作 A B 结果溢出的条件 A + B A+B A+B + + + + + + − - − A + B A+B A+B − - − − - − + + + A − B A-B A−B + + + − - − − - − A − B A-B A−B − - − + + + + + + -
双符号位补码法:对带着符号位的补码进行计算,如果计算结果前两位(符号位变为两位)
00 11 01 10 正数 负数 正溢出 负溢出 例题 \color{White}\colorbox{Fuchsia}{例题} 例题: X = + 1100 , Y = + 1000 X=+1100,Y=+1000 X=+1100,Y=+1000,求 X + Y X+Y X+Y
解: [ X ] t w o = 00 1100 , [ Y ] t w o = 00 1000 [X]_{two}={\color{red}00}1100,[Y]_{two}={\color{red}00}1000 [X]two=001100,[Y]two=001000. 相加得到 01 0100 {\color{red}01}0100 010100 表示正溢出。
例题 \color{White}\colorbox{Fuchsia}{例题} 例题: X = − 1100 , Y = − 1000 X=-1100,Y=-1000 X=−1100,Y=−1000,求 X + Y X+Y X+Y
解: [ X ] t w o = 11 0100 , [ Y ] t w o = 11 1000 [X]_{two}={\color{red}11}0100,[Y]_{two}={\color{red}11}1000 [X]two=110100,[Y]two=111000. 相加得到 1 10 1100 {\color{blue}1}{\color{red}10}1100 1101100 表示负溢出。
-
-
(一般带符号数)溢出:
-
(无符号数)溢出:可忽略——因为无符号数通常用于内存地址表示
-
算术指令:即可忽略溢出的发生,又可进行溢出的检测
- 溢出时可产生异常:add, addi, sub
- 溢出时不会异常:addu, addiu, subu
-
算术逻辑单元 Arithmetic Logic Unit:用于实行加减法和逻辑操作的硬件
- 异常 exception,中断 interrupt:产生溢出的指令地址保存在一个寄存器(EPC——Exception Progran Counter)中,然后计算机跳到预设定地址执行异常处理程序。
3.3 乘法 Multiplication
被乘数 multiplicand × \times × 乘数 multiplier = = = 积 product
-
由于二进制中只有 0 和 1 两个选择,每一步很简单
- 当乘数位为 1,将被乘数复制到合适位置
- 当乘数位为 0,将 0 复制到合适位置
-
乘法算法和硬件:
-
第一版乘法器硬件:乘数为 32 32 32 位寄存器,被乘数和乘积为 64 64 64 位寄存器
循环 32 32 32 次三步骤:
- ⨀ \color{red}\bigodot ⨀ 1. 乘数的最低位决定被乘数是否加到乘积寄存器上(当乘数最低位 = 1 =1 =1 时,乘积加上被乘数,再写入乘积寄存器)
- ⨀ \color{red}\bigodot ⨀ 2. 被乘数寄存器左移 1 1 1 位
-
⨀
\color{red}\bigodot
⨀ 3. 乘数寄存器右移
1
1
1 位(调整乘数最低位)
-
改进版乘法器硬件:(并行化来加速)当乘数位为 1 时,将乘数和被乘数进行移位,同时将被乘数和积相加。
例题 \color{White}\colorbox{Fuchsia}{例题} 例题:用 4 4 4 位长的数计算 2 10 × 3 10 2_{10}\times 3_{10} 210×310 的积
解: 001 0 2 × 001 1 2 = 000 011 0 2 0010_{2}\times 0011_2=000\; 0110_2 00102×00112=00001102
迭代次数 步骤 乘数 被乘数 乘积 0 初始值 001 1 001\color{red}1 0011 0000 0010 0000 0000 1 乘积=乘积+被乘数 0011 0000 0010 0000 0010 1 被乘数左移 0011 0000 0100 0000 0010 1 乘数右移 000 1 000\color{red}1 0001 0000 0100 0000 0010 2 改乘积,移位 000 0 000\color{red}0 0000 0000 1000 0000 0110 3 改乘积,移位 000 0 000\color{red}0 0000 0001 0000 0000 0110 4 改乘积,移位 0000 0010 0000 0000 0110 -
-
有符号数乘法:记录原来符号位,将操作数改为无符号正数得到乘积后,再对应匹配符号
-
MIPS中的乘法:
- 用两个
32
32
32 位寄存器
Hi, Lo
来容纳 64 64 64 位的乘积 - 有符号乘积
mult
,无符号乘积multu
- 用两个
32
32
32 位寄存器
3.4 除法 Division
被除数 dividend = = = 商 quotient × \times × 除数 divisor + + + 余数 remainder
-
除法算法和硬件:
-
第一种算法:商为 32 32 32 位寄存器,除数和余数均为 64 64 64 位寄存器
循环 33 \color{red}33 33 次三步骤:
- ⨀ \color{red}\bigodot ⨀ 0. 将除数放置在除数寄存器左半边(方便后续右移),余数寄存器初始化为被除数
- ⨀ \color{red}\bigodot ⨀ 1. 余数寄存器减去除数寄存内容,检查是否为正。
- ⨀ \color{red}\bigodot ⨀ 2. 商寄存器左移。若余数为正,取商为 1 1 1;若为负,余数寄存器恢复原值,取商为 0 0 0
- ⨀ \color{red}\bigodot ⨀ 3. 除数寄存器右移
例题 \color{White}\colorbox{Fuchsia}{例题} 例题:用 4 4 4 位长的数计算 7 10 ÷ 2 10 7_{10}\div 2_{10} 710÷210 的商和余数
解: 0010 011 1 2 ÷ 001 0 2 = 001 1 2 — — 000 1 2 0010\;0111_{2}\div 0010_2=0011_2——0001_2 001001112÷00102=00112——00012
迭代次数 步骤 商 除数 余数 0 初始值 0000 0010 0000 0000 0111 1 余数=余数-除数 0000 0010 0000 1 1100111 {\color{red}1}110 0111 11100111 1 余数<0,加回除数,商左移,最低为上0 0000 0010 0000 0000 0111 1 除数右移 0000 0001 0000 0000 0111 2 余数依然小于除数,商左移,最低位上0,除数右移 0000 0000 1000 0000 0111 3 余数依然小于除数,商左移,最低位上0,除数右移 0000 0000 0100 0000 0111 4 余数大于除数,商左移,最低位上1,除数右移 0001 0000 0010 0 0000011 {\color{red}0}000 0011 00000011 5 \color{red}5 5 余数大于除数,商左移,最低位上1,除数右移 0011 0000 0001 0000 0001
-
-
有符号数除法:
-
MIPS中的除法:
3.5 浮点运算
-
科学记数法 scientific notation:
- 格式化 normalized:无前导零且小数点左边只有一位整数。例: 1. 0 10 × 1 0 − 9 1.0_{10}\times 10^{-9} 1.010×10−9
- 二进制浮点数:二进制小数点不固定的表达数的记数法。例: 1. 0 2 × 2 − 1 1.0_2\times 2^{-1} 1.02×2−1
- 优点:
- 简化浮点数的数据交换
- 简化浮点算术运算
- 提高存储数的精度(因为前导零占的位被二进制小数点 binary point 右边的有效位替代)
-
浮点表示:
( − 1 ) S × ( 1 + Fraction ) × 2 Exponent − Bias \color{fuchsia}(-1)^S\times(1+\text{Fraction})\times 2^{\text{ Exponent}-\text{Bias}} (−1)S×(1+Fraction)×2 Exponent−Bias-
指数 exponent 和尾数 fraction/mantissa:在精度和表示范围间进行权衡折中
增加小数部分——增加精度,增加指数部分——增加表示范围 -
符号和数值(sign and magnitude)表示法: s s s 表示符号,指数域为8位宽(包括符号位),尾数域为23为宽
- 上/下溢出 overflow/underflow:由于正/负指数太大而不能在指数域表示,即数值太大/小
-
单精度 single precision 和双精度 double precision:
单精度:表示范围为 2. 0 10 × 1 0 − 38 ∼ 2. 0 10 × 1 0 38 \color{red}2.0_{10}\times 10^{-38}\sim 2.0_{10}\times 10^{38} 2.010×10−38∼2.010×1038
双精度:表示范围为 2. 0 10 × 1 0 − 308 ∼ 2. 0 10 × 1 0 308 \color{red}2.0_{10}\times 10^{-308}\sim 2.0_{10}\times 10^{308} 2.010×10−308∼2.010×10308
-
IEEE754 浮点标准:隐藏格式化二进制的前导位1
- 有效位 significand:24位或53位的数,即隐含的1+尾数
- 编码:其中 NaN(Not a Number) 表示非数
- 带偏阶的记数法 biased notation:为使指数域中
00...0
0
2
00...00_2
00...002 表示最小负指数,
11...1
1
2
11...11_2
11...112 表示最大正指数。(而不是补码表示形式) - 单精度的偏阶为127:
例 \color{White}\colorbox{Fuchsia}{例} 例:指数为 − 1 -1 −1时,表示为 − 1 + 12 7 10 = 12 6 10 = 0111 111 0 2 -1+127_{10}=126_{10}=0111\;1110_2 −1+12710=12610=011111102;指数为 + 1 +1 +1时,表示为 1 + 12 7 10 = 12 8 10 = 1000 000 0 2 1+127_{10}=128_{10}=1000\;0000_2 1+12710=12810=100000002- 双精度的偏阶为1023
-
例题 \color{White}\colorbox{Fuchsia}{例题} 例题:用单精度和双精度表示 − 0.7 5 10 -0.75_{10} −0.7510
解: − 0.7 5 10 = − 0.1 1 2 × 2 0 = − 1.1 × 2 − 1 -0.75_{10}=-0.11_2\times 2^0=-1.1\times 2^{-1} −0.7510=−0.112×20=−1.1×2−1- 单精度:
符号位为 1 1 1;指数位为 − 1 + 127 = 12 6 10 = 0111 111 0 2 -1+127=126_{10}=0111\;1110_2 −1+127=12610=011111102;尾数位为 − . 1000 0000 0000 0000 0000 000 -.1000\;0000\;0000\;0000\;0000\;000 −.10000000000000000000000
答案为 1011 1111 0100 0000 0000 0000 0000 0000 \text{1011 1111 0100 0000 0000 0000 0000 0000} 1011 1111 0100 0000 0000 0000 0000 0000 - 双精度:
符号位为 1 1 1;指数位为 − 1 + 1023 = 102 2 10 = 011 1111 111 0 2 -1+1023=1022_{10}=011\;1111\;1110_2 −1+1023=102210=011111111102;尾数位为 − . 100... ( 51 个 0 ) -.100...(51个0) −.100...(51个0)
答案为 1011 1111 1110 1000 ... \text{1011 1111 1110 1000 ...} 1011 1111 1110 1000 ...
- 单精度:
-
-
浮点加法:
-
浮点乘法: