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

2022-12-22 13:49:41 浏览数 (2)

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

<!--more-->

  • 从系统实现的角度来分析,多态性可分为两类,静态多态与动态多态:
  • 静态多态: 通常是通过函数或运算符的重载实现的,静态多态性又称作编译时的多态性.
  • 动态多态: 动态多态性不在编译时确定调用函数的功能,而是通过虚函数实现,它又被叫做运行时的多态性.

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

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

代码语言: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;
}

仿写汇编代码。

代码语言:text复制
	.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

0 人点赞