2017-06-05 117 views
-3

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

+0

为什么你会认为多线程*要求*指令已被移动到单个指令中? – EOF

+0

@EOF如何实现? –

+1

在一些具有固定大小指令的体系结构(如ARM(A32和AArch64),POWER MIPS等)上,这非常简单。在这样的体系结构中,您只需加载/存储一个32位定点数。再次说明,这可能与多线程相关的原因尚不清楚。 – EOF

回答

0

重新讨论如何在原始程序集中实现多线程:现代32位x86处理器支持任务切换的硬件。您可以使用它来实现多任务(具有不同地址空间的多个进程)和/或多线程(多个执行线程在一个进程中)。

此功能记录在Intel 64 and IA-32 Architectures Software Developer's Manual第3卷第7章任务管理中。 注意:阅读&了解这个可笑的密集4700页文件可能需要12寿命。

使用此硬件支持是使某些内容运行的最直接的方式,但可能不是最有效的方式。早期的基于x86的操作系统已从此转向手动任务切换。这使得系统可以实现非CPU提供的开关功能,并且在全开关过度消耗时执行优化的开关。该方法非常普遍,x86处理器的64位长模式降低了对硬件任务管理的支持。现代操作系统使用手动任务切换。


再移动指令的方式来实现多线程的想法,我想在这里你的概念是走动的地址空间代码时,切换到新的代码是必要的。有两种替代技术可以消除这种需要。

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

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

每个任务都有自己的地址空间。当切换到新任务时,系统激活其专用地址空间,然后在专用地址空间中上次暂停的地方继续执行。您不必在共享地址空间中移动任何东西,甚至不必在共享地址空间中从一个地方跳到另一个地方,而是实际定义一整组单独的地址空间。必要时您可以进入新的空间。

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


关于如何移动指令的问题,汇编语言不提供这样的能力。这不是一件常见的事情。如果你想在内存中使用机器代码,你可能会想要使用像Intel X86 Encoder Decoder library这样的库。像这样的库具有存在的指令和机器码的字节格式的知识。这使得它能够将一系列字节解释为指令。

一旦您意识到以下指令有多大,移动该数量的字节在汇编中是一件容易的事情。在x86中,您可以使用mov指令。

+0

你提到了周期性中断!我怎样才能做到这一点?我的意思是如何让CPU每5毫秒运行一组特定的代码(例如中断)? –

+0

@Anastassis适当地编程你的定时器芯片。 – fuz

+0

@fuz谢谢! –