思维导图
本文主要包括整数和浮点数的算术运算,他们都是被名为算术逻辑单元的硬件实现
一.整数运算
1.1加法
二进制数的加法采用从右到左将对应的位同进位依次相加的方式实现
//模拟二进制5+7的实现(16位)
0000 0000 0000 0101 //5
0000 0000 0000 0111 //7
0111 //进位,同左边一位的和相加
---- ---- ---- ----
0000 0000 0000 1100 //12
二进制加法会在两个正整数相加,或者两个负整数相加是出现溢出,即所得的和超出了32位可以表示的最大数和最小数.如果是有符号数则会爆出异常,因为无符号数通常表示地址,所以会被忽略.
1.2减法
二进制的减法有两种实现方式,一种是直接相减,另一种是加上被减数的相反数的二进制补码
//模拟7-5(16位)
//直接相减
0000 0000 0000 0111 //7
0000 0000 0000 0101 //5
---- ---- ---- ----
0000 0000 0000 0010 //7-5=2
//加上被减数的相反数的二进制补码
0000 0000 0000 0111 //7
1111 1111 1111 1011 //-5的二进制补码(5求反后+1)
1111 1111 1111 1111 //进位
---- ---- ---- ----
0000 0000 0000 0010 //7-5=2
同二进制加法一样,减法在正数减负数或者负数减正数时也会发生溢出.有符号数会爆出异常,无符号数会被忽略.
1.3乘法
一个乘法语句的组成是被乘数*乘数=积.其在计算机中的实现原理同手工计算乘法的原理相同(现在只考虑正整数)
//算术逻辑单元计算乘法的原理
//模拟8*9(4位)
1001 //9
1000 //8
----
0000 //乘数左边第一位乘以乘数
0000 //乘数左边第二位乘以乘数
0000 //乘数左边第三位乘以乘数
1001 //乘数左边第四位乘以乘数
-------- //四个积的和就是此乘法的积
1001000 //8+64=72
- 下图是最原始的乘法算术逻辑单元
对于操作数的每一位的三个基本执行步骤:乘数的最低为(乘数的第0 位)决定了被乘数是否被加到积寄存器上。第二步中的左移起着将被乘数左移的作用。第三部中后的有一给出了下一个迭代中要使用的乘数位。这三个步骤重复执行32次才获得积。假设每个步骤花费一个时钟周期,那么100个时钟周期才可以完成两个32位数的相乘
- 以上算术逻辑单元还可以进行优化
在这个乘法算术逻辑单元中,乘数寄存器被取消,乘数被放在乘积寄存器的右半部分,每做完一位的积并加在乘积寄存器上后,乘积寄存器就会右移一位.最后得到乘积.
还有一种更快的乘法算术逻辑单元
快速的乘法运算的主要思想是为乘数的每一位提供一个32位加法器,一个用来输入被乘数和一乘数位相与的结果,另一个是上一个加法器的输出.这样叫可以通过log2(32)=5次加法时间得到乘积,而不是等待32次加法时间
- 最后,如果乘法之中有负数时,会将负数转化为正数,然后记录其符号,得到乘积后,如果符号相异则为负数,反之则为正数.
1.4除法
- 除法逻辑单元的计算原理也同手工计算除法一样
//除法的计算原理
//模拟74/8=9...2
1001 //商 9
________ ________
1000 |1001010 //除数8 |被除数74
-1000
--------
1
10
101
1010
-1000
-----
10 //余数2
- 首先是最原始的除法算术单元
被除数会被放在余数寄存器的右半部分,而除数则会被放在除数寄存器的左半部分.每次都会让余数减去除数,若>0则将商左移一位,置位1,<0便置为0并回复余数寄存器的值.
- 除法算术单元也可以进行优化
优化原理同乘法的优化差不多.将被除数放在余数寄存器的右半部分,每次使用余数寄存器的左半部分同除数寄存器进行比较,若余数寄存器的值较大,则将余数寄存器左移并置最低位为1,否则置为0.
最后,有符号除法的处理方式同有符号乘法相同.记住符号,并将负数转化为正数,最后决定商的符号.特别的是,余数的符号被规定为 同被除数的符号相同.这样可以避免同一个除法商的值不一致的问题.例如-7 / 2 = -3...-1 也可以= -4...1
二.浮点运算
2.1二进制同十进制的转化
因为计算机底层都是对二进制数进行处理,所以,知道二进制同十进制之间是如何转化的非常必要,这篇文章写得很好,可以看看
http://www.cnblogs.com/xkfz007/articles/2590472.html-----二进制同十进制的转化方法
2.1浮点数的表示方法(单精度)
我们首先约定浮点数的表示方法:
- 科学计数法:小数点左边只有一位整数的计数方法
- 规格化数:没有前导0,即小数点左边的整数不会是0
- 基数:同十进制的科学计数法的基数为10,使小数点左移右移,二进制的基数为1*2^(-1)
所以,浮点数就是二进制小数点不固定的表达数的计数法.实际上的小数可以是无限的,但是,计算机中的小数因为物理原因限制,是有长度的,所以,浮点数也会发生上溢或者下溢.
二进制浮点数的表示格式有符号位,尾数,指数组成:
- 符号位:表示此二进制浮点数的符号,可以快速比较两个浮点数的大小,占1位即1bit
- 指数:指数表示浮点数的的指数大小是多少,占8位.为了能够快速的比较两个浮点数的大小,指数位会使用偏阶,即指数的值减去127才是真正的指数大小.如果不使用偏阶的话,因为补码的原因,负数会很大,而整数很小.
- 尾数:表示表示浮点数的小数部分,占23位.因为浮点数的表示是规格化数,会自动设置一个前导值1,即浮点数的实际小数部分=1+尾数(尾数的大小在0和1的开区间之中),这样做可以使精度扩大.
举例:-0.75(十进制)是如何表示的
首先十进制转化为二进制=-0.11(二进制)=-1.1 * 2^(-1)=-(1 + 0.1) * 2^(-1)
所以,其二进制浮点数的表示为
-0.75(十进制)的二进制浮点数表示方法
1 //符号位为1,表示负数
0111 1110 //指数位为127,实际浮点数的指数位126-127=-1
1000 000 ...(共22个0) //小数位0.1,实际浮点数为1+0.1=1.1
//综合-0.75的二进制表示为
1011 1111 0100 0000 0000 0000 0000 0000
2.2加减法
浮点数的加减法有一定的步骤.主要分为:指数对齐>>>有效数相加>>>格式化>>>舍入,具体如下
2.3乘除法
浮点数的乘除法也有一定的步骤:求指数>>>有效数相乘>>>格式化>>>舍入>>>定符号
以上说的都是单精度浮点数,双精度浮点数不同于单精度浮点数的地方在于其有11位指数,52位尾数位,其偏阶是1023.
2.4浮点运算的指令
浮点运算会使用全新的32个寄存器$f0-$f31
具体指令