让我们以将16位有符号数符号扩展到32位寄存器为例,例如mov $+/-5, %ax
movswl %ax, %ebx
。
有两种可能的情况:
1.高位为零(数字为正数)。这很容易理解和直观。例如,如果我有一个数字5
,左填充零是非常容易理解的。例如:
00000000 00000101 # 5 (represented in 16 bits)
00000000 00000000 00000000 00000101 # 5 (represented in 32 bits)
1.然而,对我来说很难理解的是,当它是一个负数时,我们进行符号扩展。示例:
11111111 11111011 # -5 (represented in 16 bits)
11111111 11111111 11111111 11111011 # -5 (represented in 32 bits)
是的,我知道我们只是用1
填充高位。但这是怎么回事?也许解释一下二进制数的什么“属性”使之成为可能会帮助我更好地理解这一点。
2条答案
按热度按时间hsgswve41#
对于
n+1
位2的补码数:-(2^n)
2^(n-1)
,依此类推(正常二进制位值)例如,在8位2的补码中,仅设置MSB的位模式表示
-128 = -(2^7)
的值。设置最高两位后,它表示-128 + 64 = -64
。当我们扩展1位时,原始符号位现在是一个“常规”位,其位值为
+(2^n)
而不是-(2^n)
,因此现有位表示的值现在比原始值高2^n + 2^n = 2^(n+1)
。(或者如果该位为零,则相同)。新的符号位的位值为
-(2^(n+1))
,因此复制原始符号位正是我们需要平衡位值变化的内容。(如果为零,则保持不变)。当然,用于一个比特的过程通过针对任何数量的比特的重复来推广。
(通常我们会使用
n
=总位数,例如对于8位2的补码,n=8而不是n=7。然后MSB的位置值是-2^(n-1)
,如果设置了它,则通过扩展新的符号位来更改其含义,添加2^n
。请参阅维基百科了解更多关于位如何表示值的信息: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位示例工作。
yvgpqqbh2#
除了Peter Cordes的精彩回答之外,我们还将在这里看到将n位数符号扩展为m位数的一般情况,其中m > n。
n位数具有十进制值:
而m位数的值为:
尾部的“
”表示两个数字中相同的术语。
如果你从m位数中减去n位数,你会得到:
正如您所看到的,当您从右到左遍历这些项时,这些项以成对的方式组合在一起。最后,我们将有:
因此,我们可以看到符号扩展在一般情况下保持了数字的值。
礼貌:https://kumom.io/articles/sign-extension