6

我需要将一个指针推入 eax 并将另一个指针推入 ebx 寄存器。我首先解决了这个问题:

register int eax asm("eax");
register int ebx asm("ebx");
int main()
{
     eax = ptr1;
     ebx = ptr2;
}

这就像一个魅力。但是,当我将它添加到我的其他代码中时,我遇到了一些奇怪的错误,即 gcc 在代码的完全不相关的部分中无法在 AREG 类中找到要溢出的寄存器。我用谷歌搜索,结果实际上是 gcc 中的一个错误-.-。所以,我需要另一种方法,将两个指针压入 eax 和 ebx 寄存器。有人有什么想法吗?

编辑:

由于人们一直在问我要在这里完成什么,我想我会解释一下。

我需要为我试图在我的程序中运行的一些汇编代码更改 eax 和 ebx。我需要执行这个汇编代码,并通过 eax 和 ebx 寄存器给参数一个指针。我通过在 ebx 中推送一个指向它的指针并调用 ebx 来执行汇编代码。当我不在全局范围内而是在本地调用寄存器时,汇编代码会崩溃。如果我全局调用它,我会在随机函数的末尾得到这个奇怪的错误。当我删除该函数时,它会在另一个随机函数中引发相同的错误。直到我用完函数,然后它才能工作,但是我错过了其余的代码:P

4

2 回答 2

6

如果您有(内联)汇编代码需要EAX/EBX中的特定参数,则在 gcc 中执行此操作的方法是使用以下内容:

__asm__("transmogrify %0, %1\n" : "+a"(val_for_eax), "+b"(val_for_ebx));

这使用 gcc 调用的内联汇编约束,它告诉编译器汇编代码 - 无论它是什么 - 期望val_for_eax/ val_for_ebxin EAX/ EBX(即a/b部分)以及它将返回这些变量的潜在修改版本(+即也注册。

除此之外,语句中的实际代码asm()对编译器来说并不重要——它只需要/想知道参数%0和位置%1。上面的例子,由于transmogrify当前 x86 指令集中不存在一条指令,在汇编器运行时会失败;只需用有效的东西代替它。

gcc 以这种方式运行的解释以及您可以告诉它做什么的解释在 GCC 手册中,位于:

您可以为变量指定特定的寄存器,但由于 gcc 的工作方式/内联汇编在 gcc 中实现的方式,这样做并不意味着(!)该寄存器从那时起保留(超出范围)供 gcc 使用为自己的目的。这只能通过约束来实现,对于特定的单个块 - 约束告诉 gcc 在放置实际汇编代码之前asm()将什么写入这些寄存器,以及之后从它们读取什么。

于 2013-05-26T07:43:32.437 回答
4

由于eax在您的体系结构上的有效程序中到处都需要寄存器,因此您的策略不能与绑定到特定寄存器的全局变量一起使用。不要那样做,全局保留寄存器不是一个好主意。

将绑定到寄存器的变量放在特定函数中,尽可能靠近它们的用途。

于 2013-05-25T16:09:17.327 回答