从汇编看c++中的默认机关函数
添加时间:2013-5-6 点击量:
c++中,若是为一个类没有明白定义一个机关函数,那么,编译器就会主动合成一个默认的机关函数。下面,经由过程汇编法度,来看一下其真实景象:。
c++中的源法度:
class X {
private:
int i;
};
int main() {
X x;
}
上方的类X没有定义机关函数,仅仅有一个int i。
下面为其汇编法度:
; 7 : int main() {
push ebp;ebp为一个存放器,老是指向一个函数调用客栈的栈底,作为基址,用偏移量来接见该调用栈上的变量,但这里没有任何变量要接见,是以不起感化
mov ebp, esp;这两句的感化是为了保存调用main之前客栈的基址ebp的值,并将ebp指向main调用栈的栈底
push ecx;将存放器ecx的值压栈, 栈顶指针esp向前移动4byte
;这句的感化,为即将要创建的对象预留了4byte的空间,并向里面写入ecx的值
; 8 : X x;
; 9 : }
xor eax, eax;eax也是一个存放器,这里不起感化
mov esp, ebp;将栈顶指针移动到push ecx前的地位,即开释了4byte的空间
pop ebp;恢复基址到main调用之前的状况
ret 0;函数返回
经由过程汇编发明,经由过程push ecx,编译器将客栈栈顶移动4byte,并将存放器的ecx的值写入,类X只含有一个int,大小正好为4byte,是以这一句可以算作是为对象x分派空间。而接下来并没有任何函数的调用,来对这一块区域进行恰当的初始化。所以,在么有明白定义一个机关函数的时辰,不会有任何的初始化操纵。
下面再看一段c++法度:
class X {
private:
int i;
int j;//增长一个成员变量int j
};
int main() {
X x;
}
与上方比拟,在类X里面增长了一个成员变量int j,类的大小变为8字节。
下面为对应汇编码:
; 8 : int main() {
push ebp
mov ebp, esp
sub esp, 8; 栈顶指针移动8byte,正好便是类X的大小
; 9 : X x;
; 10 : }
xor eax, eax
mov esp, ebp
pop ebp
ret 0
从汇编码看出,经由过程sub esp,8指令,客栈确切留出了8byte的空间,正好便是类X的大小,同样没有调用任何函数,来进行初始化操纵。
所以,综上所述,在一个类没有明白定义机关函数的时辰,编译器不会有任何的函数调用来进行初始化操纵,仅仅是移动栈顶留出对象所需空间。
以上概念纯属小我解析,迎接斧正。
我俩之间有着强烈的吸引力。短短几个小时后,我俩已经明白:我们的心是一个整体的两半,我俩的心灵是孪生兄妹,是知己。她让我感到更有活力,更完美,更幸福。即使她不在我身边,我依然还是感到幸福,因为她总是以这样或者那样的方式出现在我心头。——恩里克·巴里奥斯《爱的文明》
c++中,若是为一个类没有明白定义一个机关函数,那么,编译器就会主动合成一个默认的机关函数。下面,经由过程汇编法度,来看一下其真实景象:。
c++中的源法度:
class X {
private:
int i;
};
int main() {
X x;
}
上方的类X没有定义机关函数,仅仅有一个int i。
下面为其汇编法度:
; 7 : int main() {
push ebp;ebp为一个存放器,老是指向一个函数调用客栈的栈底,作为基址,用偏移量来接见该调用栈上的变量,但这里没有任何变量要接见,是以不起感化
mov ebp, esp;这两句的感化是为了保存调用main之前客栈的基址ebp的值,并将ebp指向main调用栈的栈底
push ecx;将存放器ecx的值压栈, 栈顶指针esp向前移动4byte
;这句的感化,为即将要创建的对象预留了4byte的空间,并向里面写入ecx的值
; 8 : X x;
; 9 : }
xor eax, eax;eax也是一个存放器,这里不起感化
mov esp, ebp;将栈顶指针移动到push ecx前的地位,即开释了4byte的空间
pop ebp;恢复基址到main调用之前的状况
ret 0;函数返回
经由过程汇编发明,经由过程push ecx,编译器将客栈栈顶移动4byte,并将存放器的ecx的值写入,类X只含有一个int,大小正好为4byte,是以这一句可以算作是为对象x分派空间。而接下来并没有任何函数的调用,来对这一块区域进行恰当的初始化。所以,在么有明白定义一个机关函数的时辰,不会有任何的初始化操纵。
下面再看一段c++法度:
class X {
private:
int i;
int j;//增长一个成员变量int j
};
int main() {
X x;
}
与上方比拟,在类X里面增长了一个成员变量int j,类的大小变为8字节。
下面为对应汇编码:
; 8 : int main() {
push ebp
mov ebp, esp
sub esp, 8; 栈顶指针移动8byte,正好便是类X的大小
; 9 : X x;
; 10 : }
xor eax, eax
mov esp, ebp
pop ebp
ret 0
从汇编码看出,经由过程sub esp,8指令,客栈确切留出了8byte的空间,正好便是类X的大小,同样没有调用任何函数,来进行初始化操纵。
所以,综上所述,在一个类没有明白定义机关函数的时辰,编译器不会有任何的函数调用来进行初始化操纵,仅仅是移动栈顶留出对象所需空间。
以上概念纯属小我解析,迎接斧正。
我俩之间有着强烈的吸引力。短短几个小时后,我俩已经明白:我们的心是一个整体的两半,我俩的心灵是孪生兄妹,是知己。她让我感到更有活力,更完美,更幸福。即使她不在我身边,我依然还是感到幸福,因为她总是以这样或者那样的方式出现在我心头。——恩里克·巴里奥斯《爱的文明》