C++ c++;by ref参数传递是否在汇编中编译?
在大学的最后几年,我上了一门关于编译器的课程。我们为C的一个子集创建了编译器。我一直想知道如何将C++中的Reby by函数调用编译成汇编。 我记得,pass by val函数调用遵循以下过程:C++ c++;by ref参数传递是否在汇编中编译?,c++,assembly,compiler-construction,C++,Assembly,Compiler Construction,在大学的最后几年,我上了一门关于编译器的课程。我们为C的一个子集创建了编译器。我一直想知道如何将C++中的Reby by函数调用编译成汇编。 我记得,pass by val函数调用遵循以下过程: 存储PP的地址 将参数推送到堆栈上 执行函数调用 在函数中,从堆栈中弹出参数 参考传递有什么不同?(int void(int&);) 编辑: 我可能听上去完全不知所措,但如果你能帮助我,我将非常感激 每个人的答案基本上是它传递的是地址而不是值。我知道传递指针基本上就是这样。那么,为什么这两个函数的行
- 存储PP的地址
- 将参数推送到堆栈上
- 执行函数调用
- 在函数中,从堆栈中弹出参数
struct A {
int x;
A(int v){
x = v;
}
};
int byRef(A& v){
v = A(3);
return 0;
}
int byP (A* v){
v = &A(4); //OR new A(4)
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
A a (1); A b (2);
byRef(a); byP (&b);
cout << a.x << " " << b.x;
system("pause");
return 0;
}
结构A{
int x;
A(国际五){
x=v;
}
};
int byRef(A&v){
v=A(3);
返回0;
}
int byP(A*v){
v=&A(4);//或新的A(4)
返回0;
}
int _tmain(int argc,_TCHAR*argv[]
{
A A(1); A b(2);;
byRef(a),byP(b),;
cout区别在于它传递的是参数的地址,而不是参数的值。您传递一个指向refereand的指针,就像传递任何其他指针一样,被调用方知道如何使用它。因此,根据实现的不同,它可能不在堆栈上-某些参数在某些堆栈的寄存器中传递呼叫约定
可能还有其他方法,因为C++标准没有指定引用是如何实现的,即使它们被实现为指针,我猜想它们可能在调用约定中被区分。但是指针是最明显的实现。
< P>我没有查看GCC的实现,但是一般的想法是,在变量的内容中传递,而不是传递到它的地址(就像C++代码使用了“*”而不是“和”在参数上)。其他方案也可用,但通常这将通过在堆栈上推送值(或地址)来实现。引用调用将涉及传递一个指向值的指针,而不是值本身的副本。如果您对血腥的细节感兴趣,您可以让编译器发出汇编语言并自己检查它 编辑:您的指针示例应该是:
int byP (A* v) {
* v = A(4); // modify thing referenced by the pointer
return 0;
}
我认为在pass by val中,程序是: *存储PP的值 *将参数推送到堆栈上 *执行函数调用 *在函数中,从堆栈中弹出参数 在passbyref中,这个过程就是你写的
干杯你可以自己看看。许多调试器允许你在“代码”视图和“反汇编”视图之间切换。我会在“代码”视图中的函数调用上设置一个断点,运行应用程序到该点,切换到程序集,然后跳过每个命令 [剧透警报] 这是一个指针
int byRef(A& v){
v = A(3);
return 0;
}
这将调用临时对象对引用传递的对象的赋值,修改函数调用中使用的对象。如果未提供赋值运算符,将执行浅层复制
int byP (A* v){
v = &A(4); //OR new A(4)
return 0;
}
这会将指向临时对象的指针复制到传入的指针值。未调用赋值函数。“v”的值已更改,但v指向的对象(作为参数传递的对象地址)不变
如果您这样做:
struct A {
int x;
A(int v){
x = v;
}
A &operator = (A &rhs){
cout << "assignment!";
}
};
当通过值传递时,编译器会发出代码,将源字节按位复制到目标变量。对于大型结构和/或频繁赋值,这可能会变得非常低效。如果您的结构重写赋值运算符,则会调用它,然后您可以控制复制的内容,但您仍然无法执行将整个结构放在堆栈上 通过引用传递时,结构的地址被推送到堆栈上,这只是一个int。这是传递大型对象最有效的方法 当通过指针传递时,指针的地址会被推送到堆栈上。必须取消对指针的引用才能获得结构的地址。这涉及到一个额外的操作
顺便说一句,byP函数中有一个严重的错误:它给指针分配了一个临时局部变量。结构是在堆栈上分配的,并且在超出范围后(很可能)会被覆盖。您必须使用“new”根据Neil Butterworth的例子,将其分配给堆,或者将结构赋值给指针,根据/tp>将所有的参数推到堆栈上就是C abi。C++可以使用可选的ABI,其中参数在寄存器中传递。“*v=A(3);“谢谢你们,伙计们!最后真的很简单。我想我想把它复杂化:)
int byRefUsingP (A *v)
{
*v = A(3);
// or you could do:
// v->operator = (A(3));
// if an operator = is defined (don't know if it will work without one defined)
return 0;
}