开发者

Converting some assembly to VB.NET - SHR operator working differently?

开发者 https://www.devze.com 2023-01-06 22:58 出处:网络
Well, a simple question here I am studying some assembly, and converting some assembly routines back to VB.NET

Well, a simple question here

I am studying some assembly, and converting some assembly routines back to VB.NET

Now, There is a specific line of code I am having trouble with, in assembly, assume开发者_如何学JAVA the following:

EBX = F0D04080

Then the following line gets executed

SHR EBX, 4

Which gives me the following:

EBX = 0F0D0408

Now, in VB.NET, i do the following

variable = variable >> 4

Which SHOULD give me the same... But it differs a SLIGHT bit, instead of the value 0F0D0408 I get FF0D0408

So what is happening here?


From the documentation of the >> operator:

In an arithmetic right shift, the bits shifted beyond the rightmost bit position are discarded, and the leftmost (sign) bit is propagated into the bit positions vacated at the left. This means that if pattern has a negative value, the vacated positions are set to one; otherwise they are set to zero.

If you are using a signed data type, F0B04080 has a negative sign (bit 1 at the start), which is copied to the vacated positions on the left.

This is not something specific to VB.NET, by the way: variable >> 4 is translated to the IL instruction shr, which is an "arithmetic shift" and preserves the sign, in contrast to the x86 assembly instruction SHR, which is an unsigned shift. To do an arithmetic shift in x86 assembler, SAR can be used.

To use an unsigned shift in VB.NET, you need to use an unsigned variable:

Dim variable As UInteger = &HF0D04080UI

The UI type character at the end of F0D04080 tells VB.NET that the literal is an unsigned integer (otherwise, it would be interpreted as a negative signed integer and the assignment would result in a compile-time error).


VB's >> operator does an arithmetic shift, which shifts in the sign bit rather than 0's.

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

should give you an equivalent value, even if it is a bit long. Alternatively, you could use an unsigned integer (UInteger or UInt32), as there's no sign bit to shift.

0

精彩评论

暂无评论...
验证码 换一张
取 消