我需要将指针移入eax,将另一个指针移入ebx寄存器。我首先解决了这个问题:
register int eax asm("eax");
register int ebx asm("ebx");
int main()
{
eax = ptr1;
ebx = ptr2;
}
这就像一个魅力。但是,当我将其添加到我的其他代码中时,我得到了一些奇怪的错误,关于gcc无法在类AREG中找到一个寄存器溢出,完全不相关的代码部分。我用Google搜索,结果实际上是gcc -.-中的一个错误。因此,我需要另一种方法,将两个指针推入eax和ebx寄存器。任何想法?
由于人们一直在问我在这里想要完成什么,我想我会解释一下。
我需要更改一些汇编代码的eax和ebx,我试图在我的程序中运行。我需要执行这个汇编代码,并通过eax和ebx寄存器给出一个指向参数的指针。我通过在ebx中推送指向它的指针执行汇编代码并调用ebx。当我不在全局调用寄存器内容时,在本地调用汇编代码崩溃。如果我全局调用它,我会在随机函数结束时得到这个奇怪的错误。当我删除该函数时,它会在另一个随机函数中抛出相同的错误。直到我用完了函数,然后才有效,但是我错过了剩下的代码:P
答案 0 :(得分:5)
如果您有(内联)汇编代码需要EAX
/ EBX
中的特定参数,那么在gcc中执行此操作的方法是使用以下内容:
__asm__("transmogrify %0, %1\n" : "+a"(val_for_eax), "+b"(val_for_ebx));
这使用了gcc调用的内联汇编约束,它告诉编译器汇编代码 - 无论它是什么 - 在val_for_eax
/中需要val_for_ebx
/ EAX
/ EBX
(这是a
/ b
部分)以及它将在这些寄存器中返回这些变量的可能修改版本(即+
)。< / p>
除此之外,asm()
语句中的实际代码对编译器无关紧要 - 它只需要/想知道参数%0
和%1
的存在位置。由于当前x86指令集中不存在transmogrify
指令,上面的示例将在汇编程序运行时失败;只需用有效的东西代替它。
为什么gcc会以这种方式行事以及你可以告诉它做什么的解释是在GCC手册中,在:
asm
operands,特别是Machine-specific Constraints list的英特尔/ 386部分,如果您需要在特定注册表中传递/检索值,该怎么说,以及Modifiers部分像+
之类的东西的含义(既传递又返回一个值;约束中还有其他类似的“修饰符”)你可以为变量指定一个特定的寄存器,但是由于gcc的工作方式/在gcc中实现内联汇编的方式,这样做并不意味着<!em>(!)寄存器从那时开始保留(超出范围),以便gcc用于自己的目的。这只能通过约束来实现,对于特定的单个asm()
块 - 约束告诉gcc在放置实际汇编代码之前写入这些寄存器的内容,以及读取的内容从他们之后。
答案 1 :(得分:4)
由于您的架构上的有效程序中需要eax
寄存器,因此您的策略无法处理绑定到特定寄存器的全局变量。不要这样做,在全球范围内保留一个注册表并不是一个好主意。
将特定函数中绑定到寄存器的变量尽可能地放在它们的使用位置。