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.
精彩评论