计算机组成与设计 读书笔记——第三章


第三章:计算机的算术运算

加法与减法

规则

  • 直接使用加法器来加
  • 减法通过加 减数的二进制补码 来实现

溢出的情况

  • 加法add和立即数 addi 可能在两个操作数同号时溢出
  • 减法sub可能在两操作数异号时发生溢出
  • 无符号加法addu 立即数无符号加法addiu和无符号减法subu不会溢出
  • 发生溢出时,MIPS会报异常

注意

addislti 一样,sltiuaddiu 虽然是无符号操作,但是16位的立即数也要符号扩展为32位,因此,操作是无符号的,但是立即数却是有符号的。


乘法

一般算法

一般用32位长去乘以32位长,然后舍去高于32位的部分。

  1. 乘积寄存器为64位 初始化为0
  2. 检查乘数最低位,如为1跳到3,为0跳到4
  3. 乘积 = 乘积 + 被乘数 跳到4
  4. 被乘数左移1位,乘数右移1位
  5. 判断是否已经重复了32次,否则跳到2
  6. 结束

有符号乘法

符号位不参与运算,同号得正,异号得负。

MIPS里的乘法

  • MIPS准备了一对32位寄存器HiLo来存64位的积
  • 乘法指令有两条,分别是mult和无符号的multu
  • 为了得到32位的积,我们需要用mflo(move from lo)
  • mfhi(move from hi)一般用于检查溢出


除法

被除数 = 商 × 除数 + 余数

一般算法

  1. 将被除数赋给余数寄存器,商寄存器为0
  2. 余数寄存器 = 余数寄存器 – 除数
  3. 若余数非负,则到4,否则到5
  4. 商寄存器左移,最低位设为1 到6
  5. 余数寄存器 = 余数寄存器 + 除数 商寄存器左移,最低位设为0 到6
  6. 除数寄存器右移1位
  7. 重复2-6共33次

有符号除法

  • 同号为正,异号为负
  • 保证余数的符号与被除数的符号相同

MIPS中的除法

  • 乘法器可以用来做除法
  • Hi中存余数,而Lo中存商


浮点运算

浮点数的表示

754标准

加法

  1. 将较小指数的数向较大指数的数对齐(右移,指数增大)
  2. 有效数字(即尾数)相加
  3. 对结果规格化调整,检查溢出
  4. 对结果进行四舍五入,如果结果不再规格化,则回到3
  5. 结束

乘法

  1. 指数部分相加,减去偏阶值作为新的指数部分
  2. 尾数相乘
  3. 对结果规格化调整,检查溢出
  4. 对结果进行四舍五入,如果结果不再规格化,则回到3
  5. 设置符号位
  6. 结束

MIPS里的浮点运算指令

  • 单精度以.s结尾,双精度以.d结尾,如add.s add.d
  • 单精度比较为c.x.s 双精度比较为c.x.d 其中x可能是eq neq lt le gt ge
  • 浮点比较为真跳转bclt 浮点比较为假跳转bclf

例题:将华氏温度转为摄氏温度

“`c++
float f2c (float fahr) {
return ((5.0/9.0) * (fahr – 32.0));
}


```shell
# fahr在$f12中 结果放在$f0中
f2c:
    lwcl  $f16,const5($gp)   # 把5.0存到$f16
    lwcl  $f18,const9($gp)   # 把9.0存到$f18
    div.s $f16,$f16,$f18     # 把5.0/9.0c存到$16
    lwcl  $f18,const32($gp)  # 把32.0存到$f18
    sub.s $f18,$f12,$f18     # $f18 = fahr - 32.0
    mul.s $f0 ,$f16,$f18     # $f0  = (5/9)*(fahr - 32.0)
    jr    $ra                 # return
点赞