views:

32

answers:

2

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 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?

+4  A: 

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).

Heinzi
Spot on - I had misread the question and tried shifting 0F0D0408 :)
Will A
Alright but how do i fix this to give me the same output in VB.NET as it does in assembly?thanks
zeta
@zeta: You need to use an unsigned variable. I've extended my answer.
Heinzi
works like a charm, just didn't know i had to add the UI, explains why i kept getting the errors when trying to make it unsignedthanks a lot!
zeta
+1  A: 

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.

cHao