目录
类的定义
demo
对象调用成员函数汇编解释
内存空间
对象的内存的排布顺序
demo
成员变量内存排布分析
对象直接访问成员变量
通过指针间接访问所指向对象的成员变量
dispaly() 的demo"> 一个p->dispaly() 的demo
类的定义
demo
#include
using namespace std;
class Persion
{
public:
int m_age;
//void run(Persion *persion){
// //显示调用
// cout << persion->m_age << " run()" <m_age << " run()" <m_age = 30;
p->run();
cout << "sizeof(persion) = " << sizeof(persion) <
对象调用成员函数汇编解释
普通函数调用对应的汇编是call xxxxx地址
persion1.run();对应的汇编:
lea ecx,[ebp-0Ch] /取地址,其中 ebp-0Ch是persion1对象的地址,ecx存储者persion1的地址
call 00061366
下面是persion1.run()调用run()过程和生成的汇编:
void run(){
this->m_age = 3;
}
内存空间
代码区 用于存放代码 上面代码块中run()内存在代码区 栈空间 1. 每调用一个函数就会给它分配一段连续的栈空间,等函数调用完毕后会自动回收这个栈空间
2.自动分配和释放
persion, persion1 以及和对应的成员在栈空间 堆空间 需要主动申请和释放 数据段(全局区) 用于存放全局变量等
对象的内存的排布顺序
对象的内存的排布顺序按照成员变量定义的顺序
demo
#include
using namespace std;
class Persion
{
public:
int m_id;
int m_age;
int m_height;
void display(){
cout << "id:" <>结果
&persion: 0x61fe14
&persion.m_id: 0x61fe14
&persion.m_age: 0x61fe18
&persion.m_height:0x61fe1c
成员变量内存排布分析
内存地址 内存数据 &persion &persion.m_id 0x00E68B60 10 0x00E68B61 0x00E68B62 0x00E68B63 &persion.m_age 0x00E68B64 20 0x00E68B65 0x00E68B66 0x00E68B67 &persion.m_height 0x00E68B68 30 0x00E68B69 0x00E68B6A 0x00E68B6B
对象直接访问成员变量
Persion persion;
persion.m_id = 10;
persion.m_height = 30;
persion.m_age = 20;
生成的汇编是:
mov dword ptr [ebp-14h],0Ah //ebp-14h是persion对象的地址值
mov dword ptr [ebp-10h],14h // ebp-10h - ebp-14h = 4个字节
mov dword ptr [ebp-0Ch],1Eh
通过指针间接访问所指向对象的成员变量
1、从指针中取出对象的地址
2、利用对象的地址+成员变量的偏移量计算成员变量的地址
3、根据成员变量的地址访问成员变量的存储空间
Persion *p = & persion;
p->m_id = 10;
p->m_height = 10;
p->m_age = 10;
p->display()
//Persion *p = & persion;
lea eax,[ebp-14h] //将persion对象的地址取出赋值给eax,ebp-14h是persion对象的地址,
mov dword ptr [ebp-20h],eax //ebp-20h是指针p的地址
//exa存储的是persion对象的地址,也就是persion.m_id的地址
// p->m_id = 10;
mov eax, dword ptr [ebp-20h] //取出指针变量p存储的内容取出放入persion对象地址
mov dword ptr [eax],0Ah //将10放入persion对象的存储空间。
注释:[]里放的是地址,[eax]中eax是地址值,dword ptr [ebp-20h] 从某个存储空间取出一个地址值说明是个指针的存储空间,可以推出ebp-20h是个指针的地址值,[ebp-20h]是指针,dword ptr [ebp-20h]是指针存储的值
mov eax, dword ptr [ebp-20h]
mov dword ptr [eax+4],0Ah // eax+4就是第二个成员变量的地址值
mov eax, dword ptr [ebp-20h]
mov dword ptr [eax+8],0Ah
mov eax, dword ptr [ebp-20h]
call 003B141F
一个p->dispaly() 的demo
class Persion
{
public:
int m_id;
int m_age;
int m_height;
void display(){
cout << "id:" <m_id = 40;
p->m_age = 50;
persion.display(); // id:10 age:40 height:50 因为将persion对象的地址传给display函数的this
p->display();// id:40 age:50 height:其他数据。因为将指针p里面存储的地址值传递给display函数的this
}
p->display(),p指向的是persion地址+4,即m_age的地址,那么在dispaly中的this->m_id,this->m_age,this->m_height,的偏移量自动加了4个字节,最终导致m_height的偏移量超过12.
对象调用成员函数汇编解释
普通函数调用对应的汇编是call xxxxx地址
persion1.run();对应的汇编:
lea ecx,[ebp-0Ch] /取地址,其中 ebp-0Ch是persion1对象的地址,ecx存储者persion1的地址
call 00061366
下面是persion1.run()调用run()过程和生成的汇编:
void run(){
this->m_age = 3;
}
内存空间
| 代码区 | 用于存放代码 | 上面代码块中run()内存在代码区 |
| 栈空间 | 1. 每调用一个函数就会给它分配一段连续的栈空间,等函数调用完毕后会自动回收这个栈空间 2.自动分配和释放 | persion, persion1 以及和对应的成员在栈空间 |
| 堆空间 | 需要主动申请和释放 | |
| 数据段(全局区) | 用于存放全局变量等 |
对象的内存的排布顺序
对象的内存的排布顺序按照成员变量定义的顺序
demo#includeusing namespace std; class Persion { public: int m_id; int m_age; int m_height; void display(){ cout << "id:" < >结果 &persion: 0x61fe14 &persion.m_id: 0x61fe14 &persion.m_age: 0x61fe18 &persion.m_height:0x61fe1c
成员变量内存排布分析
| 内存地址 | 内存数据 | ||
| &persion | &persion.m_id | 0x00E68B60 | 10 |
| 0x00E68B61 | |||
| 0x00E68B62 | |||
| 0x00E68B63 | |||
| &persion.m_age | 0x00E68B64 | 20 | |
| 0x00E68B65 | |||
| 0x00E68B66 | |||
| 0x00E68B67 | |||
| &persion.m_height | 0x00E68B68 | 30 | |
| 0x00E68B69 | |||
| 0x00E68B6A | |||
| 0x00E68B6B |
对象直接访问成员变量
Persion persion;
persion.m_id = 10;
persion.m_height = 30;
persion.m_age = 20;
生成的汇编是:
mov dword ptr [ebp-14h],0Ah //ebp-14h是persion对象的地址值
mov dword ptr [ebp-10h],14h // ebp-10h - ebp-14h = 4个字节
mov dword ptr [ebp-0Ch],1Eh
通过指针间接访问所指向对象的成员变量
1、从指针中取出对象的地址
2、利用对象的地址+成员变量的偏移量计算成员变量的地址
3、根据成员变量的地址访问成员变量的存储空间
Persion *p = & persion; p->m_id = 10; p->m_height = 10; p->m_age = 10; p->display() //Persion *p = & persion; lea eax,[ebp-14h] //将persion对象的地址取出赋值给eax,ebp-14h是persion对象的地址, mov dword ptr [ebp-20h],eax //ebp-20h是指针p的地址 //exa存储的是persion对象的地址,也就是persion.m_id的地址 // p->m_id = 10; mov eax, dword ptr [ebp-20h] //取出指针变量p存储的内容取出放入persion对象地址 mov dword ptr [eax],0Ah //将10放入persion对象的存储空间。 注释:[]里放的是地址,[eax]中eax是地址值,dword ptr [ebp-20h] 从某个存储空间取出一个地址值说明是个指针的存储空间,可以推出ebp-20h是个指针的地址值,[ebp-20h]是指针,dword ptr [ebp-20h]是指针存储的值 mov eax, dword ptr [ebp-20h] mov dword ptr [eax+4],0Ah // eax+4就是第二个成员变量的地址值 mov eax, dword ptr [ebp-20h] mov dword ptr [eax+8],0Ah mov eax, dword ptr [ebp-20h] call 003B141F
一个p->dispaly() 的demo
class Persion
{
public:
int m_id;
int m_age;
int m_height;
void display(){
cout << "id:" <m_id = 40;
p->m_age = 50;
persion.display(); // id:10 age:40 height:50 因为将persion对象的地址传给display函数的this
p->display();// id:40 age:50 height:其他数据。因为将指针p里面存储的地址值传递给display函数的this
}
p->display(),p指向的是persion地址+4,即m_age的地址,那么在dispaly中的this->m_id,this->m_age,this->m_height,的偏移量自动加了4个字节,最终导致m_height的偏移量超过12.



