【问题标题】:Asm: Moving assembly instructions to specific address [closed]Asm:将汇编指令移动到特定地址[关闭]
【发布时间】:2017-11-06 17:58:42
【问题描述】:

好吧,我正在尝试找到一条汇编指令,将整个指令移动到特定地址(与指令的大小无关)。如果没有这样的指令,谁能给我一些关于如何在没有系统调用或其他软件的情况下实现多线程的想法?换句话说,假设我正在制作自己的操作系统,如何在汇编中使用高效的代码启用多线程?

【问题讨论】:

  • 为什么你会认为多线程需要在一条指令中移动指令?
  • @EOF 如何实现?
  • 在一些具有固定大小指令的架构上非常容易,例如 ARM(A32 和 AArch64)、POWER MIPS 等。在这样的架构上,您只需加载/存储一个 32 位定点数。同样,您的问题还不清楚这可能可能与多线程相关。
  • 为什么要移动单个指令根本
  • @EOF 我只是想知道是否有这样的指令......

标签: multithreading assembly osdev


【解决方案1】:

关于如何在原始汇编中实现多线程的问题:现代 32 位 x86 处理器具有对任务切换的硬件支持。您可以使用它来实现多任务(具有不同地址空间的多个进程)和/或多线程(单个进程中的多个执行线程)。

此功能记录在Intel 64 and IA-32 Architectures Software Developer's Manual,第 3 卷,第 7 章,任务管理中。 注意:阅读和理解这份 4700 页的文档,可能需要 12 个生命周期。

使用这种硬件支持是运行某些东西最直接的方法,但可能不是最有效的方法。早期基于 x86 的操作系统从这种模式转向手动任务切换。这允许系统实现 CPU 不提供的切换功能,并且还可以在完全切换过度时执行优化切换。这种方法变得如此普遍,以至于 x86 处理器的 64 位长模式放弃了对硬件任务管理的支持。现代操作系统使用手动任务切换。


重新将移动指令作为实现多线程的一种方式的想法,我认为您的概念是在需要切换到新代码时在地址空间中移动代码。有 2 种替代技术可以消除这样做的需要。

首先,您可以跳转到不同位置的代码,而不是移动代码。早期的多任务操作系统(如 PDP-11 上的 Unix)使用了这种技术。您可以将所有活动程序加载到不同位置的内存中,设置周期性中断以每隔一段时间将控制权交给您的系统软件,并在每次中断时选择要跳转到的下一个程序。系统应跟踪每个程序停止的位置,以便它可以在同一位置恢复。

第二种方法依赖于虚拟内存。仍然有一个物理内存空间。最重要的是,定义了多个“虚拟”内存空间。在任何给定时间,只有 1 个虚拟内存空间处于活动状态。每当访问内存时,系统都会将虚拟地址转换为某个物理地址。访问内存的程序只能看到自己的虚拟地址空间。

每个任务都有自己的地址空间。当切换到一个新任务时,系统会激活它的私有地址空间,然后在它上次暂停在私有地址空间的任何地方恢复执行。您实际上不是在单个共享地址空间中移动东西,甚至不是在共享地址空间中从一个地方跳到另一个地方,而是实际上定义了一整套独立的地址空间。您可以根据需要转移到新的空间。

现代多线程在很大程度上依赖于这种方法。每个进程都会有一个私有地址空间;系统根据需要在它们之间切换。一个进程将有 1+ 个线程。进程中的每个线程共享相同的地址空间。然后,每个线程存储的所有内容都是上次暂停执行的位置。在同一进程中切换到新线程会保留当前地址空间,并在其中跳转到新线程上次暂停的位置。


关于如何移动指令的问题,汇编语言不提供这种能力。这不是一件常见的事情。如果您想对内存中的机器代码进行操作,您可能需要使用像 Intel X86 Encoder Decoder library 这样的库。像这样的库了解存在的指令和机器代码的字节格式。这使它能够将字节序列解释为指令。

一旦您知道以下指令有多大,移动该字节数在汇编中就很容易了。在 x86 中,您将使用 mov 指令。

【讨论】:

  • 你提到了周期性中断!我怎样才能做到这一点?我的意思是如何使 cpu 每 5 毫秒(例如)运行一组特定的代码(中断)?
  • @Anastassis 对你的定时器芯片进行适当的编程。
猜你喜欢
  • 1970-01-01
  • 2022-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-27
  • 1970-01-01
相关资源
最近更新 更多