Memory 无硬件支持的虚拟内存

Memory 无硬件支持的虚拟内存,memory,memory-management,operating-system,virtualization,Memory,Memory Management,Operating System,Virtualization,在阅读问题及其答案时,我不禁想,为什么硬件必须支持虚拟内存 例如,我不能仅用软件模拟此行为(例如,o.s将所有内存表示为某个表,截取所有与内存相关的操作,并自行进行映射) 有没有实现这种技术的操作系统?据我所知,没有 拦截所有与内存相关的操作?这看起来并非不可能,但我必须非常非常慢 例如,假设以下代码: int f(int *a1, int *b1, int *c1, int *d1) { const int n=100000; for(int j=0;j<n;j++){

在阅读问题及其答案时,我不禁想,为什么硬件必须支持虚拟内存

例如,我不能仅用软件模拟此行为(例如,o.s将所有内存表示为某个表,截取所有与内存相关的操作,并自行进行映射)


有没有实现这种技术的操作系统?

据我所知,没有

拦截所有与内存相关的操作
?这看起来并非不可能,但我必须非常非常慢

例如,假设以下代码:

int f(int *a1, int *b1, int *c1, int *d1)
{
    const int n=100000;

    for(int j=0;j<n;j++){
        a1[j] += b1[j];
        c1[j] += d1[j];
    }
}
即使这个非常简单的函数也有16个访问内存的机器代码。也许操作系统的模拟代码有数百个机器代码,那么我们可以猜测这个内存访问代码的速度至少会减慢数百倍

此外,在这种情况下,您只能查看内存访问代码。可能您的处理器没有此功能,您应该使用逐步调试,如x86的Trap标志,并每次检查每个命令

事情变得更糟了——光检查代码是不够的。您可能希望IP(指令指针)也遵循操作系统的虚拟内存规则,所以必须在运行每个代码后检查IP是否超出页面边界。您还必须非常小心地处理可以更改IP的代码,例如
jmp、call、ret、


我认为它不能有效地实施它无法有效地实现。速度是操作系统最重要的部分之一。如果操作系统变得有点慢,所有系统都会受到影响。在这种情况下,这一点也不重要——你的电脑变得越来越慢。此外,正如我上面所说的,实现这一点非常困难——我宁愿编写一个具有硬件支持的虚拟内存的处理器模拟器,也不愿做这项疯狂的工作

对于大多数处理器,mmu是告诉操作系统内存访问的信息。如果它不支持虚拟内存,如果不使用特殊的编译器重新编译所有代码,您可能无法在软件中实现它。这也会非常缓慢。(大概慢2-10倍)就像@programmerjake说的,速度会非常慢。实际上,您的“软件内存管理器”将把处理器变成解释器。MMU硬件允许处理器以本机方式运行可执行代码,直到硬件生成并处理页面错误中断为止。@programmerjake我正在试图了解这是否可能,我很清楚这可能会减慢速度。为什么你认为我需要重新编译所有的东西?例如,我可以编写类似模拟器的东西来实时翻译二进制文件,不是吗?(再说一遍,我不关心速度)我想你可以做到。好了,没人做过这件事,因为这就像在有锤子的情况下用羽毛钉钉子一样。@Darius是的,你可以模仿处理器。我指的是将所有内存引用转换为在编译器中进行模拟的页表查找,因为这并不是模拟整个处理器,只是mmu。是的,也不要给我提供工作:)措辞有点混乱,似乎两者都在做“疯狂的工作”(你称之为:))并对整个处理器进行仿真将实现所讨论的目标。那么为什么要大胆地拒绝呢?看起来应该是“是的,但会很慢。”(或者像模拟器一样慢,这并不完全不同)@Darius再次阅读我的最后一段(或者你已经阅读了未编辑的版本>o@Darius如果你能做到这一点,我们宁愿称之为“处理器模拟器”或“虚拟机”,而不是“操作系统”@ikh仍然,我不认为慢=不可能:)我只是认为说不然后解释怎么做是相当令人困惑的。
push   %edi                     ; 1
xor    %eax,%eax
push   %esi                     ; 2
push   %ebx                     ; 3
mov    0x10(%esp),%ecx          ; 4
mov    0x14(%esp),%esi          ; 5
mov    0x18(%esp),%edx          ; 6
mov    0x1c(%esp),%ebx          ; 7
mov    (%esi,%eax,4),%edi       ; 8
add    %edi,(%ecx,%eax,4)       ; 9
mov    (%ebx,%eax,4),%edi       ; 10
add    %edi,(%edx,%eax,4)       ; 11
add    $0x1,%eax
cmp    $0x186a0,%eax
jne    15 <_f+0x15>             ; 12
pop    %ebx                     ; 13
pop    %esi                     ; 14
pop    %edi                     ; 15
ret                             ; 16