car*_*ass 2 binary assembly bit-manipulation twos-complement sign-extension
我们以将 16 位有符号数符号扩展为 32 位寄存器为例,例如mov $+/-5, %ax movswl %ax, %ebx。
有两种可能的情况:
高位为零(数字为正)。这是非常容易理解和直观的。例如,如果我有数字5,则用零填充左侧很容易理解。例如:
00000000 00000101 # 5 (represented in 16 bits)
00000000 00000000 00000000 00000101 # 5 (represented in 32 bits)
Run Code Online (Sandbox Code Playgroud)
然而,对我来说最难理解的是当它是负数并且我们进行符号扩展时。例子:
11111111 11111011 # -5 (represented in 16 bits)
11111111 11111111 11111111 11111011 # -5 (represented in 32 bits)
Run Code Online (Sandbox Code Playgroud)
是的,我知道我们只是用 填充高位1。但是什么让它发挥作用呢?也许对二进制数的“属性”的解释可以帮助我更好地理解这一点。
对于n+12 位的补码:
-(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(全一)将是一个很好的开始值,使数学变得简单。或者0b1000(-8)是另一个不错的选择。
Google 发现https://andybargh.com/binary-sign-extension/可以通过一个 8 位示例运行。