I found some material that may be helpful in fixing some 32 bit code to run on a 64-Bit system.
Here is some code that may need to be changed followed by some info that may offer a way have it run safely.
There is a lot that I don't understand.
Do you think this material offers a way to change my code to run on a 64-Bit system?
Thanks or any help.
FShell_explodeOS PROC hb:DWORD
mov edi,hb
add edi,SPARC
mov eax,nd
dec eax
shl eax,4
@@:
fld dword ptr[edi+eax] ; x coordinate
fadd dword ptr[edi+eax+4] ; x velocity
fstp dword ptr[edi+eax]
fld dword ptr[edi+eax+8] ; y coordinate
fadd dword ptr[edi+eax+12] ; y velocity
fstp dword ptr[edi+eax+8]
sub eax,16
jnc @B
dec dword ptr[edi-SPARC]
mov eax,[edi-SPARC] ; return(--life)
ret
FShell_explodeOS ENDP
In order to discuss the potential issues with unsafe code let's explore the following example. Our managed code makes calls to an unmanaged DLL. In
particular, there is a method called GetDataBuffer that returns 100 items (for this example we are returning a fixed number of items). Each of these items
consists of an integer and a pointer. The sample code below is an excerpt from the managed code showing the unsafe function responsible for handling this
returned data.
[C#]
public unsafe int UnsafeFn() {
IntPtr * inputBuffer = sampleDLL.GetDataBuffer();
IntPtr * ptr = inputBuffer;
int result = 0;
for ( int idx = 0; idx < 100; idx ++ ) {
// Add 'int' from DLL to our result
result = result + ((int) *ptr);
// Increment pointer over int (
ptr = (IntPtr*)( ( (byte *) ptr ) + sizeof( int ) );
// Increment pointer over pointer (
ptr = (IntPtr*)( ( (byte *) ptr ) + sizeof( int ) );
}
return result;
}
Note This particular example could have been accomplished without the use of unsafe code. More specifically, there are other techniques such as
marshaling that could have been used. But for this purpose we are using unsafe code.
The UnsafeFn loops through the 100 items and sums the integer data. As we are walking through a buffer of data, the code needs to step over both the integer
and the pointer. In the 32-bit environment this code works fine. However, as we've previously discussed, pointers are 8 bytes in the 64-bit environment and
therefore the code segment (shown below) will not work correctly, as it is making use of a common programming technique, e.g., treating a pointer as
equivalent to an integer.
// Increment pointer over pointer (
ptr = (IntPtr*)( ( (byte *) ptr ) + sizeof( int ) );
In order for this code to work in both the 32-bit and 64-bit environment it would be necessary to alter the code to the following.
// Increment pointer over pointer (
ptr = (IntPtr*)( ( (byte *) ptr ) + sizeof( IntPtr ) );
As we've just seen, there are instances where using unsafe code is necessary. In most cases it is required as a result of the managed code's dependency on
some other interface. Regardless of the reasons unsafe code exists, it has to be reviewed as part of the migration process.
The example we used above is relatively simple and the fix to make the program work in 64-bit was straightforward. Clearly there are many examples of unsafe
code that are more complex. Some will require deep review and perhaps stepping back and rethinking the approach the managed code is using.
moderator edit: added [ code ] tags to improve readbility. Please use code-tags for blocks of code.