assembly - 为什么 2 的补码扩展通过添加符号位的副本来工作?
问题描述
让我们以将 16 位有符号数符号扩展为 32 位寄存器为例,例如mov $+/-5, %ax
movswl %ax, %ebx
.
有两种可能的情况:
高位为零(数字为正)。这非常容易理解和直观。例如,如果我有 number
5
,用零填充左边很容易理解。例如:00000000 00000101 # 5 (represented in 16 bits) 00000000 00000000 00000000 00000101 # 5 (represented in 32 bits)
然而,对我来说,棘手的事情是当它是一个负数并且我们进行符号扩展时。例子:
11111111 11111011 # -5 (represented in 16 bits) 11111111 11111111 11111111 11111011 # -5 (represented in 32 bits)
是的,我知道我们只是用1
. 但是是什么让它起作用呢?也许对二进制数的“属性”进行某种解释可以帮助我更好地理解这一点。
解决方案
对于 n 位 2 的补码:
- 高位(符号位)具有位置值
-(2^n)
- 下一个最高位具有位置值
2^(n-1)
,依此类推(正常二进制位置值)
当我们扩展 1 位时,原来的符号位现在是一个“常规”位,并且有一个代替的位值+(2^n)
,-(2^n)
所以现有位表示的值现在2^n + 2^n = 2^(n+1)
高于原始值。(或者如果该位为零,则相同)。
新符号位的位值为-(2^(n+1))
,因此复制原始符号位正是我们需要平衡位值变化的方法。(或者如果为零,则保持不变)。
一位的过程当然可以通过重复任意数量的位来概括。
有关位如何表示值的更多信息,请参阅维基百科:https ://en.wikipedia.org/wiki/Two%27s_complement#Converting_from_two's_complement_representation - 2 的补码文章非常好,但没有详细说明为什么要复制符号有点工作。
您也可以在纸上尝试一些小示例,例如将符号从 4 位扩展到 5 位。 -1
(全1)将是一个很好的开始,使数学变得简单。或0b1000
(-8) 是另一个不错的选择。
Google 发现https://andybargh.com/binary-sign-extension/可以通过一个 8 位示例运行。
推荐阅读
- c# - 绑定值显示:隐藏元素
- python - 处理 pandas 中的嵌套列表
- symfony - 为 Symfony 中的每个 src 文件夹设置安全性
- c# - 循环遍历 JObject 嵌套数组
- apache - 由于配置,Apache 没有启动
- arrays - 根据存储在一个范围内的多个条件对单元格进行计数
- javascript - 使用谷歌翻译器脚本错误翻译的页面中的 SvG 元素被抛出
- web-scraping - Puppeteer - 如何在 page.evaluate() 中使用 page.click()
- vba - 计算公式循环VBA的结果
- android - 从电话中提取 Cordova 资产