【问题标题】:Can Someone Explain This Code To Me?有人可以向我解释这段代码吗?
【发布时间】:2011-08-20 11:25:27
【问题描述】:

我在看这个问题: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。

【问题讨论】:

    标签: c# .net


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

        是实现乘法的汇编语言代码。对VirtualProtect 的调用是为了让代码在原本无法执行的数据段中执行。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-05-31
          • 2011-02-28
          • 1970-01-01
          • 2022-12-16
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多