Win32汇编:仿写多态与虚函数

简介: 多态性是面向对象的重要组成部分,利用多态可以设计和实现易于扩展的程序,所谓多态就是一个类函数有多重形态,具有不同功能的函数可以用同一个函数名,实现使用一个函数名调用不同内容的函数,从而返回不同的结果,这就是多态性,多态离不开虚函数的支撑,以下案例本人将深度分析虚函数实现机制,并通过汇编实现虚函数机制。

多态性是面向对象的重要组成部分,利用多态可以设计和实现易于扩展的程序,所谓多态就是一个类函数有多重形态,具有不同功能的函数可以用同一个函数名,实现使用一个函数名调用不同内容的函数,从而返回不同的结果,这就是多态性,多态离不开虚函数的支撑,以下案例本人将深度分析虚函数实现机制,并通过汇编实现虚函数机制。

  • 从系统实现的角度来分析,多态性可分为两类,静态多态与动态多态:

    • 静态多态: 通常是通过函数或运算符的重载实现的,静态多态性又称作编译时的多态性.
    • 动态多态: 动态多态性不在编译时确定调用函数的功能,而是通过虚函数实现,它又被叫做运行时的多态性.

由于对象多态性需要通过虚表和虚表指针来完成,虚表指针被定义到对象首地址前4字节处,虚表指针中保存着虚表的首地址,用于记录和查找虚函数,由于虚表指针的初始化依赖于构造函数,如果用户没有提供默认构造函数,那么编译器会自动增加。

在C++中使用关键字virtual声明函数为虚函数,我们首先编写一段C++代码,请自行反汇编观察虚函数的特性

#include <iostream>
using namespace std;

class CVirtual
{
    private:
        int m_Number;

    public:
        virtual int GetNumber()
        {
            return m_Number;
        }
        virtual void SetNumber(int num)
        {
            m_Number = num;
        }
};

int main(int argc, char* argv[])
{
    CVirtual cv;

    cv.SetNumber(5);
    printf("virtual = > %d \n", cv.GetNumber());
    return 0;
}

仿写汇编代码。

    .386p
    .model flat,stdcall
    option casemap:none

include windows.inc
include kernel32.inc
includelib kernel32.lib

; 虚表占据类前4字节
Student struct
    virtualBase DWORD 0
    x DWORD 0
Student ends

.data
    stu Student <>
    
    virtual_table DWORD 0,0,0,0,0,0,0dh

.code

    SetNumber PROC
    
    SetNumber ENDP


    GetNumber PROC
        
        ret

    GetNumber ENDP
    
    
    ; 模拟构造函数,初始化虚表指针
    Init PROC
        
        ; 将虚表指针首地址放入到类的开头位置
        mov dword ptr [stu],ecx
        
        ; 构建函数表
        mov dword ptr [virtual_table],offset GetNumber
        mov dword ptr [virtual_table+4h],offset SetNumber
        
        ret

    Init ENDP

    main PROC
        push ebp
        mov ebp,esp
        sub esp,0f4h
        push ebx
        push esi
        push edi
        lea edi,dword ptr [ ebp - 0f4h ]
        mov ecx,03dh
        mov eax,0CCCCCCCCh
        rep stosd
        
        lea ecx,stu           ; 获取类的首地址
        call Init             ; 调用构造函数
        pop edi
        pop esi
        pop ebx
        add esp,0f4h
        mov esp,ebp
        pop ebp
        ret
    main ENDP
END main
目录
相关文章
|
8月前
|
搜索推荐 算法 编译器
5.13 汇编语言:仿写For循环语句
循环语句(for)是计算机编程中的一种基本控制结构,它允许程序按照指定的次数或范围重复执行一段代码块。for循环在处理需要进行迭代操作的情况下非常有用,它使得程序可以更加方便地控制循环的次数。一般来说,for循环由三个部分组成:初始化部分、条件表达式和更新部分,以及一个需要重复执行的代码块。在每次循环迭代开始时,程序首先执行初始化部分,然后检查条件表达式的值,如果为真,则执行代码块,并在每次循环结束后执行更新部分。只要条件表达式为真,for循环就会一直重复执行;一旦条件表达式为假,循环将停止,程序继续执行循环之后的代码。
55 0
|
8月前
|
算法 编译器 C++
5.12 汇编语言:仿写While循环语句
循环语句(While)一种基本控制结构,它允许程序在条件为真的情况下重复执行一段代码块,直到条件为假为止。循环语句在处理需要重复执行的任务时非常有用,它可以让程序更加高效地处理大量数据或者重复性操作。一般来说,While循环由一个条件表达式、一个代码块组成。在每次循环迭代开始时,程序会首先检查条件表达式的值,如果为真,则执行代码块,然后再次检查条件表达式的值。只要条件表达式为真,循环就会一直继续执行;一旦条件表达式为假,循环将停止,程序继续执行循环之后的代码。
83 0
|
8月前
|
存储 编译器 索引
5.14 汇编语言:仿写Switch选择结构
选择结构,也称为switch语句,是计算机编程中的一种控制结构,用于根据表达式的值选择不同的执行路径。它允许程序根据表达式的值来决定执行哪个代码块,从而实现多分支选择逻辑。switch语句由一个表达式、多个case标签以及对应的代码块组成。程序会将表达式的值与每个case标签进行匹配,一旦找到匹配的case标签,程序将执行对应的代码块,并继续执行该代码块之后的代码,直到遇到break语句或者switch语句结束。
62 0
|
8月前
|
编译器 C语言 C++
5.11 汇编语言:仿写IF条件语句
条件语句,也称为IF-ELSE语句,是计算机编程中的一种基本控制结构。它允许程序根据条件的真假来执行不同的代码块。条件语句在处理决策和分支逻辑时非常有用。一般来说,条件语句由IF关键字、一个条件表达式、一个或多个代码块以及可选的ELSE关键字和对应的代码块组成。条件表达式的结果通常是布尔值(True或False),决定了程序将执行IF代码块还是ELSE代码块。
58 0
|
数据安全/隐私保护
Win32汇编:算术与伪指令
每种汇编语言都有进行操作数移位的指令,移位和循环移位指令在控制硬件设备,加密数据,以及实现高速图形运算时特别有用,移位指令也是汇编语言中最具特征的指令集,`移位(Shifting)`的含义是在操作数内向左或向右移动数据位,Intel处理器提供了多种移位指令,具体如下表所示:
244 0
|
存储 编译器 API
Win32汇编:过程与宏调用
在计算机领域,堆栈是一个不容忽视的概念,堆栈是一种`后进先出(LIFO,Last-In,First-Out)`的数据结构,这是因为最后压入堆栈的值总是最先被取出,而新数值在执行PUSH压栈时总是被加到堆栈的最顶端,数据也总是从堆栈的最顶端被取出,堆栈是个`特殊的存储区`,主要功能是暂时存放数据和地址,通常用来保护断点和现场.
89 0
|
存储 编译器
Win32汇编:算数运算指令总结
汇编中常用的运算符,加减乘除等,另外包括了移位运算等,移位又分为,算数移位,逻辑移位,循环移位,双精度移位等。
113 0
|
存储 编译器
Win32汇编:数组与标志位测试总结
整理复习汇编语言的知识点,以前在学习《Intel汇编语言程序设计 - 第五版》时没有很认真的整理笔记,主要因为当时是以学习理解为目的没有整理的很详细,这次是我第三次阅读此书,每一次阅读都会有新的收获,这次复习,我想把书中的重点,再一次做一个归纳与总结(注:16位汇编部分跳过),并且继续尝试写一些有趣的案例,这些案例中所涉及的指令都是逆向中的重点,一些不重要的我就直接省略了,一来提高自己,二来分享知识,转载请加出处,敲代码备注挺难受的。
224 0
|
存储 编译器 C语言
Win32汇编:各种语句的构造方式
整理复习汇编语言的知识点,以前在学习《Intel汇编语言程序设计 - 第五版》时没有很认真的整理笔记,主要因为当时是以学习理解为目的没有整理的很详细,这次是我第三次阅读此书,每一次阅读都会有新的收获,这次复习,我想把书中的重点,再一次做一个归纳与总结(注:16位汇编部分跳过),并且继续尝试写一些有趣的案例,这些案例中所涉及的指令都是逆向中的重点,一些不重要的我就直接省略了,一来提高自己,二来分享知识,转载请加出处,敲代码备注挺难受的。
181 0
|
存储 编译器 C语言
Win32汇编:字符串浮点数运算过程
整理复习汇编语言的知识点,以前在学习《Intel汇编语言程序设计 - 第五版》时没有很认真的整理笔记,主要因为当时是以学习理解为目的没有整理的很详细,这次是我第三次阅读此书,每一次阅读都会有新的收获,这次复习,我想把书中的重点,再一次做一个归纳与总结(注:16位汇编部分跳过),并且继续尝试写一些有趣的案例,这些案例中所涉及的指令都是逆向中的重点,一些不重要的我就直接省略了,一来提高自己,二来分享知识,转载请加出处,敲代码备注挺难受的。
232 0
Win32汇编:字符串浮点数运算过程