Generally, executing native assembly in C# is bad because you lose all the benefits of the managed world. In the cases where it is impossible to perform something in C#, it is better to make a C++ DLL. That said, the new method Marshal.GetDelegateForFunctionPointer() in the .NET Framework v2.0 opens up the possibility for dynamically writing and executing assembly code. Consider the following basic C function:


int __declspec(noinline) __stdcall MyAdd(int x, int y)
{
    return x + y;
}

The C compiler will compile the code into assembly. Though the code which gets compiled may vary from compiler to platform, for x86 it will usually have this basic form:


Instruction                 Code Bytes   Comment
------------------------------------------------------------------------------
mov eax,dword ptr [esp+8] ' 8B 44 24 08  Load the x into eax
mov ecx,dword ptr [esp+4] ' 8B 4C 24 04  Load the y into ecx
add eax,ecx               ' 03 C1        Add eax and ecx, result goes into eax
ret 8                     ' C2 08 00     Pop x and y off the stack, return eax

The instructions listed are disassembly copied from the VC++ debugger. The code bytes are what actually executes. The idea is to take those code bytes, write them into a native buffer, acquire a delegate for that buffer, and finally execute the delegate. Here is sample code to run these code bytes from C#:


using System; 
using System.Runtime.InteropServices;




class Program
{
    private delegate Int32 MyAdd(Int32 x, Int32 y);

    private static void Main() 
    {
        // A simple Add function
        Byte[] myAddNativeCodeBytes = new Byte[]
        {
            0x8B, 0x44, 0x24, 0x08, // mov eax,dword ptr [esp+8]
            0x8B, 0x4C, 0x24, 0x04, // mov ecx,dword ptr [esp+4]
            0x03, 0xC1,             // add eax,ecx
            0xC2, 0x08, 0x00        // ret 8
        };

        // We need to push the code bytes into a native buffer
        IntPtr myAddNativeCodeBytesPtr = IntPtr.Zero;

        try
        {
            // Allocate the native buffer
            myAddNativeCodeBytesPtr =
                Marshal.AllocCoTaskMem(myAddNativeCodeBytes.Length);

            // Push the code bytes over
            Marshal.Copy(myAddNativeCodeBytes, 0,
                myAddNativeCodeBytesPtr, myAddNativeCodeBytes.Length);

            // Get a function pointer for the native code bytes
            MyAdd myAdd = (MyAdd)Marshal.GetDelegateForFunctionPointer(
                myAddNativeCodeBytesPtr, typeof(MyAdd));

            // Call the native code bytes
            Int32 result = myAdd(4, 5);

            // Did it work?
            Console.WriteLine("Result: {0}", result);
        }

        finally
        {
            // Free the native buffer
            if (myAddNativeCodeBytesPtr != IntPtr.Zero)
            {
                Marshal.FreeCoTaskMem(myAddNativeCodeBytesPtr);
                myAddNativeCodeBytesPtr = IntPtr.Zero;
            }
        }
    }
}

In this sample I just used Marshal.AllocCoTaskMem(), but one should actually P/Invoke VirtualAllocEx and VirtualProtectEx to ensure the page where the code exists has PAGE_EXECUTE access. Additionally the above sample is targetted to my personal x86 machine, and will not run on x64 or any other platform for that matter.