当前位置: 首页 > 面试题库 >

如何动态生成和运行本机代码?

孙嘉
2023-03-14
问题内容

我想为我编写的(纯粹是学术性的)玩具语言处理器编写一个非常小的概念验证JIT编译器,但是在中等高度的设计中遇到了一些麻烦。从概念上讲,我熟悉JIT的工作原理-
您将字节码编译为(机器或汇编语言)代码以运行。但是,从细节上讲,我不太 了解 您实际如何 执行 此操作。

我(非常“ newb”)下意识的反应,因为我没有从哪里开始的第一个线索,将尝试执行以下操作:

  1. mmap()一个内存块,设置对PROT_EXEC的访问
  2. 将本机代码写入块
  3. 将当前寄存器(堆栈指针等)存储在舒适的某个位置
  4. 修改当前寄存器以指向映射区域中的本机代码块
  5. 本机代码现在将由计算机执行
  6. 恢复以前的寄存器

这甚至 接近
/正确的算法吗?我尝试细读我知道有JIT编译器要研究的不同项目(例如V8),但是由于它们的大小,这些代码库很难使用,而且我也不知道从哪里开始寻找。


问题答案:

不确定linux,但这适用于x86 / windows。
更新:http://codepad.org/sQoF6kR8

#include <stdio.h>
#include <windows.h>

typedef unsigned char byte;

int arg1;
int arg2;
int res1;

typedef void (*pfunc)(void);

union funcptr {
  pfunc x;
  byte* y;
};

int main( void ) {

  byte* buf = (byte*)VirtualAllocEx( GetCurrentProcess(), 0, 1<<16, MEM_COMMIT, PAGE_EXECUTE_READWRITE );

  if( buf==0 ) return 0;

  byte* p = buf;

  *p++ = 0x50; // push eax
  *p++ = 0x52; // push edx

  *p++ = 0xA1; // mov eax, [arg2]
  (int*&)p[0] = &arg2; p+=sizeof(int*);

  *p++ = 0x92; // xchg edx,eax

  *p++ = 0xA1; // mov eax, [arg1]
  (int*&)p[0] = &arg1; p+=sizeof(int*);

  *p++ = 0xF7; *p++ = 0xEA; // imul edx

  *p++ = 0xA3; // mov [res1],eax
  (int*&)p[0] = &res1; p+=sizeof(int*);

  *p++ = 0x5A; // pop edx
  *p++ = 0x58; // pop eax
  *p++ = 0xC3; // ret

  funcptr func;
  func.y = buf;

  arg1 = 123; arg2 = 321; res1 = 0;

  func.x(); // call generated code

  printf( "arg1=%i arg2=%i arg1*arg2=%i func(arg1,arg2)=%i\n", arg1,arg2,arg1*arg2,res1 );

}


 类似资料:
  • 我有一个由Quarkus添加到构建时初始化的第三方类,但由于静态线程使用,它需要运行时初始化。将其添加到运行时初始化本机构建时,会抱怨它同时存在于这两个版本中。 重新生成此文件的示例项目:https://github.com/hshorter/quarkus-avro-decode-example 使用“--initialize-at-run-time=org.apache.avro.specif

  • 问题内容: 我需要在运行时为方法生成代码。能够运行任意代码并具有文档字符串非常重要。 我想出了一个结合和的解决方案,这是一个虚拟的示例: 是否有更好/更安全/更惯用的方式获得相同的结果? 问题答案: 基于Theran的代码,但将其扩展为类的方法: 应该打印:

  • 目前,我正在生成表头和行,但我希望使行更具动态性。如何在不重复一次的情况下打印行的数据?我怎样才能像标题一样使用1语句呢?所以基本上我只需要调用{row},它应该生成该行包含的所有内容,而不必键入{row.school}等等。。。

  • 问题内容: 在maven中,使用以下语法在pom中设置属性非常容易: 现在,我需要构建一个取决于pom版本的属性。为了创建属性,我想执行以下操作(java伪代码): 它应该是动态的,因为它在我们的存储库中用作标记名,并且必须始终与工件的版本同步。 任何想法如何创建该“动态”属性? 问题答案: Mojo的Build-Helper Maven插件可以在这里为您提供帮助。 有许多目标可用于帮助转换属性。

  • 问题内容: 我正在尝试在我的网站上生成QR码。他们要做的就是在其中包含一个URL,该URL将在我的网站上提供。最简单的方法是什么? 问题答案: 值得补充的是,除了@abaumg发布的QR码库外,Google还提供了一个 [QR Code API] QRCodes API非常感谢链接更新。 要使用this,基本上是: 是您要生成的QR图像的尺寸, 这是您要更改为QR码的url编码的字符串,并且 的是