我正在考虑编写一个JIT编译器,只是想知道在理论上是否有可能用托管代码编写整个代码.具体地说,一旦将汇编器生成字节数组,如何跳到其中开始执行?

推荐答案

为了充分证明这一概念,这里将Rasmus的JIT方法翻译成F#

open System
open System.Runtime.InteropServices

type AllocationType =
    | COMMIT=0x1000u

type MemoryProtection =
    | EXECUTE_READWRITE=0x40u

type FreeType =
    | DECOMMIT = 0x4000u

[<DllImport("kernel32.dll", SetLastError=true)>]
extern IntPtr VirtualAlloc(IntPtr lpAddress, UIntPtr dwSize, AllocationType flAllocationType, MemoryProtection flProtect);

[<DllImport("kernel32.dll", SetLastError=true)>]
extern bool VirtualFree(IntPtr lpAddress, UIntPtr dwSize, FreeType freeType);

let JITcode: byte[] = [|0x55uy;0x8Buy;0xECuy;0x8Buy;0x45uy;0x08uy;0xD1uy;0xC8uy;0x5Duy;0xC3uy|]

[<UnmanagedFunctionPointer(CallingConvention.Cdecl)>] 
type Ret1ArgDelegate = delegate of (uint32) -> uint32

[<EntryPointAttribute>]
let main (args: string[]) =
    let executableMemory = VirtualAlloc(IntPtr.Zero, UIntPtr(uint32(JITcode.Length)), AllocationType.COMMIT, MemoryProtection.EXECUTE_READWRITE)
    Marshal.Copy(JITcode, 0, executableMemory, JITcode.Length)
    let jitedFun = Marshal.GetDelegateForFunctionPointer(executableMemory, typeof<Ret1ArgDelegate>) :?> Ret1ArgDelegate
    let mutable test = 0xFFFFFFFCu
    printfn "Value before: %X" test
    test <- jitedFun.Invoke test
    printfn "Value after: %X" test
    VirtualFree(executableMemory, UIntPtr.Zero, FreeType.DECOMMIT) |> ignore
    0

这很好

Value before: FFFFFFFC
Value after: 7FFFFFFE

.net相关问答推荐

找不到包Microsoft.VisualStudio.Azure.Containers.Tools.Targets

无法在Ubuntu 22.04.3上运行带有Rider 2023和DotNet-8.0的项目

如何通过在后台预加载流项来优化流迭代的性能?

在 Inno Setup 中判断给定服务的依赖服务

StreamWriter.Flush() 和 StreamWriter.Close() 有什么区别?

将 int 转换为 .NET 中的位数组

如何获取 Sql Server 数据库中所有模式的列表

有没有办法以编程方式最小化窗口

什么决定了 Path.GetTempPath() 的返回值?

是否有用于 Windows / C# 开发的可嵌入 Webkit 组件?

如何将 NuGet 与 Visual C# Express 一起使用?

你如何调试 MVC 4 API 路由?

在 .NET (C#) 中本地存储数据的最佳方式

所有数组在 C# 中都实现了哪些接口?

向 .NET 应用程序添加脚本功能

返回 IList 是否比返回 T[] 或 List 更糟糕?

通过反射查找可空属性的类型

具有不同身份验证标头的 HttpClient 单个实例

如何从 webclient 获取状态码?

如何在我的机器上找到 fuslogvw.exe?