正在获取在寄存器中传递的参数的地址 C++中具有传递值,调用方构造被调用方使用的副本。在x64 ABI中,一些参数在寄存器中传递。寄存器没有地址
因此,假设我有以下类:正在获取在寄存器中传递的参数的地址 C++中具有传递值,调用方构造被调用方使用的副本。在x64 ABI中,一些参数在寄存器中传递。寄存器没有地址,c++,cpu-registers,calling-convention,C++,Cpu Registers,Calling Convention,因此,假设我有以下类: class Self_Pointer { Self_Pointer* self; Self_Pointer(const Self_Pointer& obj) : self(this) {} } 当作为参数传递时,它接受指向自身的指针。现在我有了这个函数: f(Self_Pointer x) {} f()。f()的调用方必须在寄存器中创建副本。因此,调用方将在寄存器中的Self_指针上运行构造函数。但是,寄存器没有地址,因此无法运行构造函数。这一
class Self_Pointer
{
Self_Pointer* self;
Self_Pointer(const Self_Pointer& obj) : self(this) {}
}
当作为参数传递时,它接受指向自身的指针。现在我有了这个函数:
f(Self_Pointer x) {}
f()。f()
的调用方必须在寄存器中创建副本。因此,调用方将在寄存器中的Self_指针上运行构造函数。但是,寄存器没有地址,因此无法运行构造函数。这一困境如何解决
[编辑:根据Steve Jessop的回答,将类的ctor修复为复制ctor。]不,您不能。您得到的地址始终是RAM的虚拟地址。不能直接访问C++中的登记地址。< /P> < P>不,不能。您得到的地址始终是RAM的虚拟地址。不能直接访问C++中的寄存器地址。< P>使用登记器(或堆栈,用于参数传递)是特定编译器的实现细节。为了获得要传递给函数的地址,编译器将寄存器的值复制到内存中的一个临时位置(通常在堆栈上),将其地址传递到它需要去的任何地方,然后根据需要将数据从临时位置加载回同一个寄存器。使用寄存器(或堆栈)参数传递是特定编译器的实现细节。为了获得要传递给函数的地址,编译器将寄存器的值复制到内存中的临时位置(通常在堆栈上),将其地址传递到需要传递的任何位置,然后根据需要将数据从临时位置加载回同一寄存器。首先,Self\u指针的副本不指向自身。它指向原始,因为编译器生成的复制构造函数将self
的值从原始复制到副本
因此,当您通过复制将对象传递到f
时,实际上x
并不指向自身
如果您通过为Self\u指针
编写合适的副本构造函数来修复此问题,则需要实现以确保x
具有地址。如果这意味着不在寄存器中传递它,那么它就不会在寄存器中传递。通常,ABI不会在寄存器中传递结构,除非它们是聚合类型,而您的示例不是这样,因为它有一个用户定义的构造函数
另一个例子是,考虑:
void foo(int i) {
std::cout << &i << '\n';
}
void foo(inti){
std::cout首先,Self\u指针的副本不指向自身。它指向原始指针,因为编译器生成的副本构造函数将Self
的值从原始指针复制到副本
因此,当您通过复制将对象传递到f
时,实际上x
并不指向自身
如果您通过为Self\u指针
编写合适的复制构造函数来修复此问题,则需要实现以确保x
具有地址。如果这意味着不在寄存器中传递它,则不会在寄存器中传递它。通常,ABI不会在寄存器中传递结构,除非它们是聚合类型,您的示例不是这样的,因为它有一个用户定义的构造函数
另一个例子是,考虑:
void foo(int i) {
std::cout << &i << '\n';
}
void foo(inti){
std::cout如果你真的想知道,查看生成的程序集总是最好的方法。我试过了,但我看不懂程序集。如果你真的想知道,查看生成的程序集总是最好的方法。我试过了,但我看不懂程序集。