assembly 为什么2的补码符号扩展通过添加符号位的副本来工作?

camsedfj  于 2023-06-30  发布在  其他
关注(0)|答案(2)|浏览(84)

让我们以将16位有符号数符号扩展到32位寄存器为例,例如mov $+/-5, %axmovswl %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填充高位。但这是怎么回事?也许解释一下二进制数的什么“属性”使之成为可能会帮助我更好地理解这一点。

hsgswve4

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位示例工作。

yvgpqqbh

yvgpqqbh2#

除了Peter Cordes的精彩回答之外,我们还将在这里看到将n位数符号扩展为m位数的一般情况,其中m > n。
n位数具有十进制值:

而m位数的值为:

尾部的“

”表示两个数字中相同的术语。
如果你从m位数中减去n位数,你会得到:

正如您所看到的,当您从右到左遍历这些项时,这些项以成对的方式组合在一起。最后,我们将有:

因此,我们可以看到符号扩展在一般情况下保持了数字的值。
礼貌:https://kumom.io/articles/sign-extension

相关问题