什么阻止我使用ASM跳转到任何绝对地址?

Jos*_* H. 3 assembly operating-system

什么阻止我执行jmp @9274592即使它超出我的程序的限制?我不是直接写入CPU吗?在我假设的操作系统中,究竟是什么阻止命令被执行?

Tob*_*ght 11

这取决于您的操作系统和硬件.在现代系统中,操作系统控制硬件提供的内存保护.


在20世纪80年代的典型微处理器中,没有什么能阻止存储空间中任何地方的访问(包括执行) - 并且错误的代码可能会使机器崩溃.对于具有协作式多任务处理的早期单用户计算机也是如此,例如DOS和原始Mac.

在现代工作站级机器中,处理器包括一个内存管理单元(MMU),用于控制对内存的访问.最广泛使用的机制是虚拟内存,具有每页权限位.每个进程都有自己的虚拟地址空间.


诸如Unix或Linux之类的操作系统写入MMU以指定当前进程可以读取/写入/执行哪些页面(写入MMU是进程本身无法完成的特权操作).

在没有执行权限的情况下跳转到页面中的某个位置将导致处理器陷阱; 这会将处理器切换到特权模式并进入内核,然后内核可以决定做什么.通常,这意味着向SIGSEGV进程发送信号(这就是为什么您可能会看到类似Segmentation fault程序崩溃时的错误消息).

当在时间分片环境中同时运行多个用户进程,在每个上下文切换时切换MMU内容是内核的工作.在地址空间交换机上使TLB无效的成本(以及由此产生的TLB未命中)可构成分时系统中的主要开销.

  • 我做了一些编辑,所以你的答案听起来不像是在描述带有 68020 和独立 MMU 的“现代”1985 Sun 工作站。(哈哈,我刚刚用 google 搜索了一下,我猜到了 [Sun-3 的正确年份和 CPU](https://en.wikipedia.org/wiki/Sun-3))。任何具有虚拟寻址和高速缓存的 CPU 都会将 MMU 基本上集成到核心中(或者每个核心,如果多个核心),因为高速缓存通常是物理标记的,因此在检查标记之前需要地址转换。一些设计使用虚拟标记的 L1 缓存来避免对真正高速 TLB 的需要,但仍然如此。 (2认同)
  • 你编写程序的语言并不重要; 一旦编译完成,它只是机器代码.当你调用`exec()`时,编译的文件指示操作系统将可执行代码放在(虚拟)内存中,并允许访问执行它.如果您为变量和/或常量保留了存储空间,那么也可以在可执行文件中指明.您可能在运行时请求更多内存(C++用户将使用`new`或`malloc`),如果内核愿意,它将为您的进程添加更多可访问的内存.所以CPU和OS**一起工作**来管理你的进程内存. (2认同)