2011-05-06 153 views
6

我在看這個問題:How to implement multiplication without using multiplication operator in .NET,實際上有很多樂趣,試圖想辦法繁殖而不使用*。有人可以向我解釋這段代碼嗎?

但是我在這個答案上一直在撓頭。我不知道這段代碼是怎麼回事。

有人可以解釋給我嗎?

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 == sizeof(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(); } 
    } 
} 

此代碼的信用轉至Mehrdad。

回答

12

它基本上是從本地代碼乘法,然後調用它創建一個委託。字節數組是原始指令,然後固定在內存中,設置爲可執行,然後Marshal.GetDelegateForFunctionPointer正在創建委託本身。

條件運算符是爲x86和x64使用不同的本機代碼。我懷疑在ARM處理器上運行Mono時會失敗,例如:)

3

此代碼包含CPU指令的二進制文件。它找到二進制的地址並執行它。除了作爲一個消極的例子或笑話之外,這很糟糕。

1

它是實現乘法的彙編語言代碼。 VirtualProtect的調用是爲了使代碼執行在本來不可執行的數據段中。

+0

實際上是本機機器碼,而不是彙編語言。 – 2011-05-07 11:51:11

相關問題