Assembly 我教科书中的算术右移示例在MSB为零时进行右移

Assembly 我教科书中的算术右移示例在MSB为零时进行右移,assembly,bitwise-operators,bit-shift,Assembly,Bitwise Operators,Bit Shift,我目前正在研究汇编,以及它们之间的位操作的工作方式。尤其是算术右移让我感到困扰 现在,在我正在阅读的书中,有几个实践问题,其中,我需要对一个字节执行此操作,该字节包括: 0100 0100 现在,由于算术右移填充了最高有效位的值,在我看来,这应该是正确的: 00001000 然而,这本书说它应该是 11101000 也就是说,从左侧填充1,而不是0。但最重要的不是0吗 嗯,还有一个: 0110 0100 >> 3 = 0000 1100 但是,显然这也是错误的,而且应该是:

我目前正在研究汇编,以及它们之间的位操作的工作方式。尤其是算术右移让我感到困扰

现在,在我正在阅读的书中,有几个实践问题,其中,我需要对一个字节执行此操作,该字节包括:

0100 0100
现在,由于算术右移填充了最高有效位的值,在我看来,这应该是正确的:

00001000
然而,这本书说它应该是

11101000
也就是说,从左侧填充1,而不是0。但最重要的不是0吗

嗯,还有一个:

0110 0100 >> 3 = 0000 1100
但是,显然这也是错误的,而且应该是:

11101100
再一次,我不明白,最重要的比特值显然是0,最左边的那个,但解决方案告诉我应该填入1


我这里有最后一个显然是正确的:

0111 0010 >> 3 = 0000 1110
这就是我所期望的。那么为什么其他人不正确呢


如果不理解这一点,读取汇编是非常困难的,因为许多乘法和除法都被编译成移位运算。

左移位是基幂的增加,右移位是基幂的减少。所以基数2(二进制)右移是2的幂次递减,左移是递增。右除以2,左乘以2

问题在于右移和负数,这意味着假设两个数是互补的,并且理解处理器不知道或不关心,位就是位,它们对程序员意味着什么

负的两个补码表示msbit已按您清楚的理解设置

所以,如果我想将-2 0B111110除以2得到-1 0B111111,最好是右移,但逻辑右移通常意味着用零填充顶部,所以逻辑右移的0B111110变成0B011111,而不是-1,它是127。一些处理器有一个算术右移,它不会在零中移动,而是复制顶部位,因此0b11111110 ASR变为0B11111。 这是使用移位除以-2/2的正确/理想答案

同样,请理解0b11111110同时也表示值254和254/2=127。所以算术右移给出255,这是错误的答案。到目前为止,对于已签名的LSR,我们希望对未签名的LSR进行ASR

你是对的,你的书可能是错的,或者你只是给了我们书的片段

0b01000100 ASR is 0b00100010
0b01000100 LSR is 0b00100010
0b10001000 ASR is 0b11000100
0b10001000 LSR 0s 0b01000100
多位算术移位只需将其视为多个单位,或者仅用原始数字的msbit填充顶部

0b10001000 ASR 3=0bBBB10001,其中B为1,因此0b11110001 对于LSR,BBBE为0 0b00010001


请注意,算术左移和逻辑左移是相同的操作,它们只是从右边填充零。

说到C,这可能是书中的一个错误,根据:

  • 无符号类型上的移位按预期工作(要移位的位数必须小于要移位的位数的宽度,且为非负)
  • 在有符号类型上转换是不同的。如果要移位的数字为负数,则左移位未定义,而右移位由实现定义
因此,无符号数上的移位是有明确定义的,但无符号数上的移位不是有符号数(更确切地说,没有一个通用的定义)

为完整起见,本标准规定:

E1>>E2的结果是E1右移E2位位置。如果E1具有无符号类型或E1具有有符号类型和非负值,则结果值为E1/2E2商的整数部分。如果E1具有有符号类型和负值,则结果值是实现定义的()

所以考虑到OP的例子(正数),没有理由用自己的来填充

谈论算术移位(让我们举个例子):

在算术移位(也称为有符号移位)中,与逻辑移位一样,从末尾滑出的位消失(最后一位进入进位标志的位除外)。但在算术移位中,空格的填充方式是保留数字滑动的符号。因此,算术移位更适合于2的补码格式的有符号数

当数字为负数时,
SAR
指令将填入one's(以保留符号),例如:

sar 10110011b,2#结果是11101100b

shr 10110011b,2#结果是00101100b

但同样,OP的例子讲的是正数,所以没有理由用自己的正数来填充


总之,当应用右移时,可以用1填充,但在这些情况下不行。

当输入的MSB为0时,任何移位都不会用1填充。请注意,相反的情况不正确(逻辑右移总是用零填充)

如果这本书没有额外的上下文,那么它只是一个错误。这不是一个旋转或其他任何东西。即使是1的补码或符号/大小也不能解释它(因为在所有3种表示中,数字都是正数)

符号位副本中2的补码移位的算术右移。(例如,
sar eax,31
将符号位广播到32位寄存器的所有位

算术移位结果的符号将始终与输入的符号相同。


逻辑右移总是以零移位


左移位对于逻辑和算术是相同的:它们以零移位。(x86有一个,但它只是与shl相同操作码的一个替代名称。以后的x86扩展不需要提及算术左移位,例如,有一个SIMD(压缩整数左移位逻辑),但没有
pslad