有人可以向我解释这段代码吗?

本文关键字:代码 段代码 可以向 解释 | 更新日期: 2023-09-27 17:55:26

我正在研究这个问题:如何在不使用 .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。

有人可以向我解释这段代码吗?

它基本上是从本机代码创建一个用于乘法的委托,然后调用它。字节数组是原始指令,然后固定在内存中,设置为可执行,然后Marshal.GetDelegateForFunctionPointer创建委托本身。

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

此代码包含 CPU 指令的二进制文件。它找到二进制文件的地址并执行它。除了作为负面例子或笑话之外,非常糟糕。

实现乘法是汇编语言代码。 对VirtualProtect的要求是在原本不可执行的数据段中启用代码执行。