3
|
Lance Pollard · 技术社区 · 7 年前 |
![]() |
1
7
以下是目前常用的主要CPU上运行的主要操作系统。在旧的或一些嵌入式操作系统上(特别是在没有虚拟内存的操作系统上,情况要简单得多),或者在没有操作系统的情况下运行代码,或者在不支持内存保护的CPU上运行代码时,情况会有所不同。 你问题中的情况有点简单。它没有显示的一点是(虚拟)内存是由操作系统提供给您的页面组成的。每个页面都有自己的权限,控制您的进程是否可以读取、写入和/或执行该页面中的数据。 二进制文件的文本部分将加载到可执行但不可写的页面上。只读数据节将加载到既不可写也不可执行的页面上。图片中的所有其他内存((未)初始化数据、堆、堆栈)将存储在可写但不可执行的页面上。 这些权限可防止安全缺陷(如缓冲区溢出),否则攻击者可以通过使程序跳入攻击者提供的代码或让攻击者覆盖文本部分中的代码来执行任意代码。 现在,关于JIT编译,这些权限的问题是,您无法执行JIT编译的代码:如果您将其存储在堆栈或堆(或全局变量内),它将不在可执行页上,因此当您尝试跳入代码时,程序将崩溃。如果试图将其存储在文本区域(通过使用最后一页上的剩余内存或覆盖JIT编译器代码的部分),程序将崩溃,因为您试图写入只读内存。
但谢天谢地,操作系统允许您更改页面的权限(在POSIX系统上,可以使用
要防止这些问题,可以使用函数,例如
因此,大多数JIT编译器的工作方式是使用
|
![]() |
2
-1
堆和堆栈是程序在运行时可以分配的内存区域。这并不特定于V8或JIT编译器。关于更多细节,我谦恭地建议您阅读该插图来自的任何书籍;-) |
![]() |
George S. · 是否存在基于元组的控制流语句内部表示? 7 年前 |
![]() |
FlatAssembler · 在x86程序集中计算exp(x) 7 年前 |
![]() |
cib · 即时编译和动态编译有什么区别? 7 年前 |
![]() |
Artemis · 寄存器与指令之间的差异 7 年前 |
![]() |
Sam · 了解go工具编译和链接命令 7 年前 |