首页 > 编程语言 >用汇编的眼光看C++(之虚函数)

用汇编的眼光看C++(之虚函数)

时间:2022-11-23 11:00:57浏览次数:45  
标签:汇编 mov C++ ebp dword employee 之虚 ptr ecx


    虚函数是面向对象设计中的一个重要内容。它的出现使得我们只需要相同的接口函数,并可以得到不同的生成结果。但是有些朋友却知其然,不知其所以然,为什么会出现这样的结果,我们可以用一段代码说明问题。首先,我们先定义两个基本类型,一个是employee,一个是manager,看过前面一片博客的朋友应该都有点印象:

class employee
{
public:
employee() { }
~employee() {}
virtual void print() const { printf("employee!\n");}
};

class manager : public employee
{
public:
manager() {}
~manager() {}
void print() const {printf("manager!\n");}
};

    我们看到,和前面出现的成员函数稍微有一些不同,这里的print函数之前出现了virtual。然而正是这个virtual发挥了巨大的作用。可以毫不夸张地说,没有虚函数,基本上就没有设计模式,也就无法体现C++语言在面向对象设计中的巨大优越性。下面我们看看这个virtual是怎样发挥作用的?

76:       employee p;
0040128D lea ecx,[ebp-10h]
00401290 call @ILT+45(employee::employee) (00401032)
00401295 mov dword ptr [ebp-4],0
77: manager m;
0040129C lea ecx,[ebp-14h]
0040129F call @ILT+65(manager::manager) (00401046)
004012A4 mov byte ptr [ebp-4],1
78: employee* e = &p;
004012A8 lea eax,[ebp-10h]
004012AB mov dword ptr [ebp-18h],eax
79: e->print();
004012AE mov ecx,dword ptr [ebp-18h]
004012B1 mov edx,dword ptr [ecx]
004012B3 mov esi,esp
004012B5 mov ecx,dword ptr [ebp-18h]
004012B8 call dword ptr [edx]
004012BA cmp esi,esp
004012BC call __chkesp (00408870)
80: e = &m;
004012C1 lea eax,[ebp-14h]
004012C4 mov dword ptr [ebp-18h],eax
81: e->print();
004012C7 mov ecx,dword ptr [ebp-18h]
004012CA mov edx,dword ptr [ecx]
004012CC mov esi,esp
004012CE mov ecx,dword ptr [ebp-18h]
004012D1 call dword ptr [edx]
004012D3 cmp esi,esp
004012D5 call __chkesp (00408870)
82: }

    上面是一段函数调用的代码,代码可以稍微有点长。不过没有关系,我们可以按照代码的行数一行一行地去进行说明和理解。

    76行: 我们创建了employee类型的一个变量p,这个可以从后面的employee的构造函数可以看出来

 77行:

    78行: 我们创建一个指针临时变量e,它保存了变量p的地址,这一句也比较简单

    79行: 我们发现79句下面共有7句汇编,其中第三句、第六句、第七句是平衡堆栈的时候用的,和我们的调用没有关系。那么call的edx是什么东西呢?原来函数调用的顺序是这样的:edx -> [ecx]  ->[ebp-0x18],不知道大家看明白了没有。在内存的第一个字节记录一个指向print函数指针的指针,也就是edx。通过这个edx,我们就可以查找到位于edx地址的内容是什么。后来我们提取出来后发现[edx]的内容正是我们要查找的print函数地址。这里相当于一个二次寻址的过程。

    80行: 我们重新对临时变量e进行了赋值,此时e保存的是变量m的地址

81行:


    试想一下,如果没有这个virtual函数,以上这段代码会发生什么差别呢?

76:       employee p;
0040127D lea ecx,[ebp-10h]
00401280 call @ILT+45(employee::employee) (00401032)
00401285 mov dword ptr [ebp-4],0
77: manager m;
0040128C lea ecx,[ebp-14h]
0040128F call @ILT+65(manager::manager) (00401046)
00401294 mov byte ptr [ebp-4],1
78: employee* e = &p;
00401298 lea eax,[ebp-10h]
0040129B mov dword ptr [ebp-18h],eax
79: e->print();
0040129E mov ecx,dword ptr [ebp-18h]
004012A1 call @ILT+5(employee::print) (0040100a)
80: e = &m;
004012A6 lea ecx,[ebp-14h]
004012A9 mov dword ptr [ebp-18h],ecx
81: e->print();
004012AC mov ecx,dword ptr [ebp-18h]
004012AF call @ILT+5(employee::print) (0040100a)
82: }

    很遗憾,这里就没有了动态查找的过程,所有的打印函数最终都指向了函数employee::print,此时多态性也不复存在了。



标签:汇编,mov,C++,ebp,dword,employee,之虚,ptr,ecx
From: https://blog.51cto.com/u_15888909/5880576

相关文章

  • 用汇编的眼光看C++(之类继承)
       继承是类的一个基本属性,可是在类的继承过程中,函数是怎么初始化?怎么析构的呢?我们不妨看看下面这样的一段代码?classemployee{public:employee(){printf("employee......
  • C/C++模拟校园卡
    C/C++模拟校园卡模拟校园卡出题人:俞琼面向专业:物联网工程难度等级:41问题描述同学们都在机房做实验或自由上机,请根据自己实际使用情况编写一份模拟校园卡消费记录查......
  • C++学校图书馆管理系统
    C++学校图书馆管理系统一、实验目的1.掌握结构体类型的声明方法;2.掌握结构体变量、结构体数组、结构体指针的定义和初始化的方法;3.掌握向函数传递结构体变量、结构体数......
  • c++ 调用 python 2.7
    本来想调用python3.10的,但一直安装不成功,先记录一下python2.7。先上代码:#include<iostream>usingnamespacestd;#include"Python.h"intmain(intargc,cha......
  • P1644 跳马问题 C++ 搜索回溯+dfs
    题目背景在爱与愁的故事第一弹第三章出来前先练练四道基本的回溯/搜索题吧……题目描述中国象棋半张棋盘如图1所示。马自左下角(0,0)向右上角(m,n)跳。规定只能往......
  • P2819 图的m着色问题 C++ 详细题解
    题目背景给定无向连通图G和m种不同的颜色。用这些颜色为图G的各顶点着色,每个顶点着一种颜色。如果有一种着色法使G中每条边的2个顶点着不同颜色,则称这个图是m可着色的。图......
  • [C++]二进制求子集
    这几天做[leetcode1178]猜字谜的题目,用到了很多小的知识技巧点。其中一个就是二进制状态压缩以及如何根据一个二进制序列求其子集,如二进制序列110111001子集里有000000001......
  • Dev-C++5.11安装教程
    (目录)一、下载1.介绍原公司Bloodshed已经停止开发Dev-C++了,但是Embarcadero开发着一个Dev-C++的分支。详见:https://www.embarcadero.com/cn/free-tools/dev-c......
  • 如何利用C++使Windows蓝屏
    如何利用C++使Windows蓝屏虽说windows非常强大,但是使它蓝屏也非常简单:如果你想让Windows蓝屏,你一定会在运行框里输入:cmd/cfor/f%Iin('wmicprocessgetName')d......
  • C/C++个人帐本管理系统
    C/C++个人帐本管理系统程序设计题3:个人帐本管理系统指导老师:吴家皋[email protected]【问题描述】该系统要求实现一个简单、实用的个人帐本管理程......