将一些程序集转换为VB.NET - SHR运算符的工作方式不同?

时间:2010-07-11 22:42:26

标签: vb.net assembly bit-shift disassembly

嗯,这是一个简单的问题

我正在研究一些程序集,并将一些程序集例程转换回VB.NET

现在,有一段特定的代码我在汇编时遇到了麻烦,假设如下:

EBX = F0D04080

然后执行以下行

SHR EBX, 4

这给了我以下内容:

EBX = 0F0D0408

现在,在VB.NET中,我执行以下操作

variable = variable >> 4

哪个应该给我相同......但是它与SLIGHT位不同,而不是值0F0D0408我得到FF0D0408

那么这里发生了什么?

2 个答案:

答案 0 :(得分:4)

来自>> operator的文档:

  

在算术右移中,丢弃超出最右位位置的位,并且最左边(符号)位传播到左侧空出的位位置。这意味着如果模式具有负值,则腾出的位置设置为1;否则它们被设置为零。

如果您使用的是签名数据类型,F0B04080会有一个负号(开头位1),会被复制到左侧空出的位置。

这不是VB.NET特有的东西,顺便说一句:variable >> 4被翻译为IL instruction shr,这是一个“算术移位”并保留符号,与x86程序集形成对比指令SHR,这是一个无符号的移位。要在x86汇编程序中进行算术移位,可以使用SAR

要在VB.NET中使用无符号移位,您需要使用无符号变量:

Dim variable As UInteger = &HF0D04080UI

F0D04080末尾的UI type character告诉VB.NET文字是无符号整数(否则,它将被解释为负有符号整数,并且赋值将导致编译 - 时间错误)。

答案 1 :(得分:1)

VB的>>运算符执行算术移位,它在符号位而不是0位移位。

variable = (variable >> shift_amt) And Not (Integer.MinValue >> (shift_amt - 1))

应该给你一个等价的值,即使它有点长。或者,您可以使用无符号整数(UInteger或UInt32),因为没有符号位可以移位。