有人能向我解释一下这段代码吗?

6
我在看这个问题:如何在.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。
3个回答

12

这基本上是从本地代码中创建一个乘法代理,然后调用它。字节数组是原始指令,然后将其固定在内存中,设置为可执行,然后 Marshal.GetDelegateForFunctionPointer 即创建代理。

条件运算符是为x86和x64使用不同的本机代码。我怀疑在例如ARM处理器上运行Mono时,这可能会失败 :)


3
这段代码包含CPU指令的二进制代码。它找到二进制代码的地址并执行。除了作为反面教材或笑话外,这种做法并没有什么实际价值。

1

这是汇编语言代码来实现乘法。调用VirtualProtect的目的是在本来是非可执行数据段中启用代码执行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接