2014-09-24 125 views
0

我开始了我在汇编程序,我正在做一些算法和通用寄存器的数量是不够的,这IA32-86使用专用寄存器作为通用寄存器

有什么办法在asm中使用特殊寄存器(eip,eflags)作为通用寄存器?

我只需要它们进行少量操作,但所有通用寄存器都已占用,我不喜欢将值存储在内存中,这会降低算法的性能。

可能吗?

+3

您可以通过执行'jmp value'来写入'eip'。你可以通过'call foo; foo:pop eax;'但是第一个可能有你不想要的副作用。 :)总之,没有你不能使用'eip'和'eflags'作其他用途。 (并且大多数算术指令会隐式写入'eflags') – Mysticial 2014-09-24 19:21:35

+2

几乎你不能以实际的方式使用寄存器来达到预期的目的。如果您是汇编程序的新手,您可能还不知道如何组织代码以最大限度地降低注册压力。而在某些地方,您只是明确地坚持特定算法的要求。作为一般规则,如果您仔细编码,您的代码将运行得足够快。编码合理,让它先运行,然后*担心它是否太慢。 – 2014-09-24 19:52:39

+0

你可以用'sahf'将'ah'的某些位保存到'eflags'中,然后用'lahf'将它们加载到'ah'。您也可以使用'popf'将数据存储到标志中,但这可能会产生不必要的副作用。在实模式代码(legacy或boot loader)中,你可以用cli来阻塞中断,然后在某处存储esp,使用esp作为通用寄存器,加载esp的原始值并允许中断'sti'。你可以使用'eip'来存储一些数据。用'jmp eax' /'call eax',如果所有使用的值(跳转目标)都有有效的代码。无论如何,出于实际的目的,你最好遵循Ira Baxter的建议。 – nrz 2014-09-24 23:35:06

回答

0

简短的回答是否定的。

如果你正在运行一个程序,使用eip作为通用寄存器是绝对不可能的,就像你写入eip一样,你的程序将跳转到该地址的运行指令(大致),这可能不会工作....至于EFLAGS,它有一些位被保留或控制你不想改变的各种事物,这又意味着它不能用作通用寄存器。由于您似乎有意不使用内存来保留值,因此可以使用esp和ebp(如果您使用堆栈,请小心)。除此之外,如果您将它们用作通用寄存器,则我认为您使用的大多数寄存器都需要许可级别0来写入并重新写入,否则很可能会产生负面影响。

有可能是一些非常特殊的寄存器,特定于您的处理器,但如果您要使用它们,代码将不会在处理器之间移植。

+0

在实模式和虚拟模式下,段寄存器(DS,ES,FS和GS,也可能是SS - 如果SP被错用)也可用于存储通用数据。然而,这些寄存器可以完成的操作非常有限。 – 2014-09-24 20:28:34

2

明智地重用已经可用的通用寄存器可能是您最好的选择。仔细想想你的算法。

重新调整EIP是不可能的,并且使用EFLAGS作为别的东西,虽然也许是可能的,但是太多的副作用通常是有用的。

更好的方法是实际使用内存计算您的算法。您可能会发现,由于缓存,访问速度并不像您想象的那么慢。

另一个选择是使用数学协处理器的寄存器作为一个小的私有堆栈来存储,但这也可能不如简单地使用存储器那么令人满意。

2

简短回答:不可以。那些寄存器并不打算明确写入。你必须重写你的算法,更好地分配你的寄存器,处理智能地溢出/重新加载寄存器到内存以最小化性能影响,或者如果可能的话,使用XMM寄存器来移动INT寄存器,或者在XMM方面做指令链。另一种选择是使用64位来利用可用的额外寄存器。

0

我记得我使用调试寄存器dr0来存储数据dr3。但我不确定他们使用的速度有多快。也许CPU内部的寄存器重命名(用于构建微操作)也可以让它更高效。