I was looking at this question: How to implement multiplication without using multiplication operator in .NET and actually had a lot of fun trying to think of ways to multiply without using *.
But I was left scratching my head at this answer. I have no idea what is going on in this code.
Can someone explain it to me?
using System;
using System.Runtime.InteropServices;
delegate uint BinaryOp(uint a, uint b);
static class Program
{
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool VirtualProtect(
IntPtr address, IntPtr size, uint protect, out uint oldProtect);
static void Main()
{
var bytes = IntPtr.Size == siz开发者_开发百科eof(int) ? //32-bit? It's slower BTW
new byte[] {0x8B, 0x44, 0x24, 0x04, 0x0F, 0xAF, 0x44, 0x24, 0x08, 0xC3}
: new byte[] {0x0F, 0xAF, 0xCA, 0x8B, 0xC1, 0xC3};
var handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
try
{
uint old;
VirtualProtect(handle.AddrOfPinnedObject(),
(IntPtr)bytes.Length, 0x40, out old);
var action = (BinaryOp)Marshal.GetDelegateForFunctionPointer(
handle.AddrOfPinnedObject(), typeof(BinaryOp));
var temp = action(3, 2); //6!
}
finally { handle.Free(); }
}
}
Credit for this code goes to Mehrdad.
It's basically creating a delegate from the native code for multiplication, and then invoking it. The byte arrays are the raw instructions, which are then pinned in memory, set to be executable, and then Marshal.GetDelegateForFunctionPointer
is creating the delegate itself.
The conditional operator is to use different native code for x86 and x64. I suspect this would fail when running on Mono on an ARM processor, for example :)
This code contains the binary of CPU instructions. It finds the address of the binary and executes it. Pretty awful except as a negative example or a joke.
It is assembly language code to implement multiplication. The call for VirtualProtect
is to enable code execution in what would otherwise be a non-executable data segment.
精彩评论