好吧,我正在尝试查找将整个指令移动到特定地址(与指令大小无关)的汇编指令。如果没有这样的指令,有人可以给我一些关于如何在没有系统调用或其他软件的情况下实现多线程的想法吗?换句话说,让我们假设我正在创建自己的操作系统,如何在汇编中使用高效代码启用多线程?
答案 0 :(得分:0)
重新讨论如何在原始组件中实现多线程:现代32位x86处理器具有对任务切换的硬件支持。您可以使用它来实现多任务(具有不同地址空间的多个进程)和/或多线程(在单个进程中有多个执行线程)。
此功能记录在Intel 64 and IA-32 Architectures Software Developer's Manual,第3卷,第7章,任务管理中。 注意:阅读&理解这个荒谬密集的4700页文档可能需要12个生命周期。
使用此硬件支持是最直接的方式来运行但可能不是最有效的。早期基于x86的操作系统从此转向手动任务切换。这允许系统实现CPU未提供的切换功能,并且当完整切换过度时也执行优化的切换。这种方法变得如此普遍,以至于64位长模式的x86处理器降低了硬件任务管理支持。现代操作系统使用手动任务切换。
将移动指令作为实现多线程的一种方法的想法,我认为你的概念是在需要切换到新代码时在代码周围移动代码。有两种替代技术可以消除这种需要。
首先,您可以跳转到不同位置的代码,而不是移动代码。早期的多任务操作系统(如PDP-11上的Unix)使用了这种技术。您可以将所有活动程序加载到不同位置的内存中,设置周期性中断以便经常将控制权丢弃到系统软件中,并在每个中断上选择要跳转到的下一个程序。系统应该跟踪每个程序停止的位置,以便它可以在同一个地方恢复。
第二种方法取决于虚拟内存。仍然只有一个物理内存空间。最重要的是,多个"虚拟"内存空间已定义。在任何给定时间只有1个虚拟内存空间处于活动状态。无论何时访问内存,系统都会将虚拟地址转换为某个物理地址。访问内存的程序只能看到自己的虚拟地址空间。
每个任务都有自己的地址空间。切换到新任务时,系统会激活其专用地址空间,然后在私有地址空间中上次暂停的任何位置恢复执行。您实际上定义了一整套独立的地址空间,而不是在单个共享地址空间中移动内容,甚至在共享地址空间中从一个地方跳转到另一个地方。你可以根据需要转移到新的空间。
现代多线程在很大程度上取决于这种方法。每个进程都有一个私有地址空间;系统根据需要在它们之间转换。一个进程将有1个线程。进程中的每个线程共享相同的地址空间。然后,每个线程存储的所有内容都是上次暂停执行的位置。在同一进程中切换到新线程会保留当前地址空间,并且只需在其中跳转到新线程上次暂停的位置。
关于如何移动指令的问题,汇编语言不提供这样的能力。这不常见。如果你想在内存中操作机器代码,你可能想要使用像Intel X86 Encoder Decoder library这样的库。像这样的库知道存在的指令和机器代码的字节格式。这使它能够将字节序列解释为指令。
一旦你意识到以下指令有多大,移动这个字节数就很容易在汇编中完成。在x86中,您将使用mov
指令。