2011-05-06 15 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(); } 
    } 
} 

इस कोड के लिए क्रेडिट मेहरदद जाता है।

उत्तर

12

यह मूल रूप से गुणन के लिए देशी कोड से एक प्रतिनिधि बनाने है, और फिर इसे लागू। बाइट एरे कच्चे निर्देश होते हैं, जिन्हें स्मृति में पिन किया जाता है, निष्पादन योग्य सेट किया जाता है, और फिर Marshal.GetDelegateForFunctionPointer प्रतिनिधि स्वयं बना रहा है।

सशर्त ऑपरेटर x86 और x64 के लिए विभिन्न देशी कोड का उपयोग करना है। मुझे संदेह है कि एआरएम प्रोसेसर पर मोनो पर चलने पर यह असफल हो जाएगा, उदाहरण के लिए :)

3

इस कोड में सीपीयू निर्देशों का बाइनरी शामिल है। यह बाइनरी का पता पाता है और इसे निष्पादित करता है। एक नकारात्मक उदाहरण या एक मजाक के अलावा बहुत भयानक।

1

यह गुणा लागू करने के लिए असेंबली भाषा कोड है। VirtualProtect के लिए कॉल कोड निष्पादन को सक्षम करने के लिए है जो अन्यथा गैर-निष्पादन योग्य डेटा सेगमेंट होगा।

+0

वास्तव में मूल मशीन कोड, असेंबली भाषा नहीं। –

संबंधित मुद्दे