扩展和移位

682 字
3 分钟
扩展和移位

扩展和移位#

符号扩展#

当把短位宽的带符号数存入长位宽寄存器时,需要对多出的位进行填充。符号扩展的对象是带符号数

正数的扩展#

符号位不变(= 0),所有扩展位用 0 填充。

  • 整数向左扩展填 0
  • 小数向右扩展填 0

例:8 位 +500000101)→ 16 位 00000000 00000101

负数的扩展#

取决于该负数用的是何种编码:

原码表示#

方向规则
整数在符号位和数值位之间填充 0
小数在数值位之后填充 0

例:8 位原码 -5 = 10000101 → 16 位 = 10000000 00000101

补码表示#

方向规则
整数向左扩展,填充符号位(即 1)
小数向右扩展,填充 0

例:8 位补码 -5 = 11111011 → 16 位 = 11111111 11111011

补码整数扩展时填符号位(而非 0)是保证数值不变的关键。填 0 的话 11111011 会变成 00000000 11111011 = 251,而不是 −5。

溢出判断(乘法)#

两个 int(32 位)相乘得到 64 位乘积,但寄存器只能保留低 32 位。如何判断溢出?

64位乘积:1111 1111 1111 1111 1111 │ 1111 1111 ... 0010 0000 1111 0111
←────── 高 32 位 ────────→│←─────── 低 32 位 ───────────────→
红色虚线:32位寄存器截断位置

判断规则:查看高 32 位是否全是 0(正数)或全是 1(负数补码)。如果不是,说明低 32 位表示不了完整的 64 位结果 → 溢出。


移位操作#

左移#

xkx \ll k:x 向左移动 k 位,右端补 k 个 0。每左移一位相当于乘以 2

右移#

xkx \gg k:x 向右移动 k 位。分为两种:

类型左端填充适用场景
逻辑右移补 k 个 0无符号数
算术右移补 k 个最高位的值(符号位)带符号数

算术右移示例#

x=1100x = 1100(补码表示 −4),算术右移 2 位:

1100 ──算术>>2──→ 1111
补码: -4 补码: -1
(除以 4)

算术右移 2 位 = 除以 22=42^2 = 44÷4=1-4 \div 4 = -1

算术右移保持了符号,逻辑右移不保持。


补码加减运算电路#

一个电路同时实现加法和减法,关键是利用补码的性质:Y=Yˉ+1-Y = \bar{Y} + 1

┌────────────┐
Sub ─┤ Cin │
│ │
X ──────────────────┤ │──────→ F (结果)
│ 加法器 │
┌──┐ ┌───────┤ ├──→ Cout
Y ────┤~ ├──┤ 1 │ │──→ OF
└──┘ │ MUX │ │──→ SF
│ │ │──→ ZF
Y ───┤ 0 │ │──→ CF
└──┬────┘ │
│ ┌───────────┘
Y'
Sub(控制信号)MUX 输出 YY'Cin实际运算
0Y=YY' = Y(选通 0 端)0F=X+YF = X + Y(加法)
1Y=YˉY' = \bar{Y}(选通 1 端)1F=X+Yˉ+1=XYF = X + \bar{Y} + 1 = X - Y(减法)

::: tip Sub == Cin 减法时 Sub=1,同时把 Cin 也置为 1,从而完成 Yˉ+1=Y\bar{Y} + 1 = -Y 的转换。 :::

扩展和移位
https://dongyanzhang.com/posts/计算机组成原理/扩展和移位/
作者
阿东阿言
发布于
2026-07-14
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
阿东阿言
I share my notes | projects | experience here...
公告
欢迎来到阿东阿言的博客
音乐
封面

音乐

暂未播放

0:000:00
暂无歌词
分类
标签
站点统计
文章
25
分类
3
标签
5
总字数
11,186
运行时长
0
最后活动
0 天前
站点信息
构建平台
Local
博客版本
v1.0.0
文章许可
CC BY-NC-SA 4.0