将指针推入GCC中的eax和ebx寄存器

问题描述 投票:6回答:2

我需要将指针推入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

c gcc assembly x86 cpu-registers
2个回答
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以及它将返回这些变量的可能修改版本(也就是+)也在这些寄存器中。

除此之外,asm()语句中的实际代码对编译器无关紧要 - 它只需要/想要知道参数%0%1所在的位置。由于当前x86指令集中不存在transmogrify指令,上面的示例将在汇编程序运行时失败;只需用有效的东西代替它。

解释为什么gcc以这种方式表现,以及你可以告诉它做的正是在GCC手册中,在:

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


4
投票

由于eax寄存器需要在架构上的有效程序中遍布所有位置,因此您的策略无法使用绑定到特定寄存器的全局变量。不要这样做,在全球范围内保留一个寄存器并不是一个好主意。

将绑定到特定函数中的寄存器的变量放在尽可能接近其使用的位置。

© www.soinside.com 2019 - 2024. All rights reserved.