从汇编学习c++ 之 类的方法调用

src(debug vesion by vs2008 sp1 on xp sp3)

#include<iostream>
using namespace std;

class SimpleClass{
public:
    int x;
    void HelloWorld(){
        printf("hello,mao");
    }
};

int main(int argc,char **argv)
{
    SimpleClass myclass;
    myclass.HelloWorld();
    return 0;
}

反汇编后的结构

--- c:\vc6\myprojects\vsclasstest\vsclasstest\bingome.cpp ----------------------
 1: #include<iostream>
 2: using namespace std;
 3:
 4: class SimpleClass{
 5: public:
 6:     int x;
 7:     void HelloWorld(){
00411440  push ebp
00411441  mov ebp,esp
00411443  sub esp,0CCh
00411449  push ebx
0041144A  push esi
0041144B  push edi
0041144C  push ecx
0041144D  lea edi,[ebp-0CCh]
00411453  mov ecx,33h
00411458  mov eax,0CCCCCCCCh
0041145D  rep stos dword ptr es:[edi]  //将局部变量空间全部初始化为0xcc (0x33*4=CC)(store to string addr edi by dword,repeat time is ecx,filled-word is eax.)
0041145F  pop ecx
00411460  mov dword ptr [ebp-8],ecx    //ebp-8处是个变量,存放当前类实例的地址,那么,我们的x去了哪里呢。--类中的变量不是函数中的局部变量,方法和类成员没有关系。
 8:         printf("hello,mao");
00411463  mov esi,esp
00411465  push offset string "hello,mao" (415800h)
0041146A  call dword ptr [__imp__printf (4182BCh)] //从导入表中获得地址,导入表iat在4182BCh处
00411470  add esp,4
00411473  cmp esi,esp
00411475  call @ILT+310(__RTC_CheckEsp) (41113Bh)
 9:     }
0041147A  pop edi
0041147B  pop esi
0041147C  pop ebx
0041147D  add esp,0CCh
00411483  cmp ebp,esp
00411485  call @ILT+310(__RTC_CheckEsp) (41113Bh)
0041148A  mov esp,ebp
0041148C  pop ebp
0041148D  ret

main函数部分

17:     SimpleClass myclass;
18:     myclass.HelloWorld();
 004113CE  lea ecx,[myclass]
 004113D1  callSimpleClass::HelloWorld (41114Ah)
19:     return 0;
 004113D6  xor eax,eax

从图中可以看出来,执行类中方法的时候,会先取出实例化类的地址(ecx= myclass),也就是说编译器让类的内部方法实现的时候已经引入了隐藏变量实例化的类指针

类中的变量不是类方法中的变量,类方法访问类中变量是通过ecx作为隐藏参数传入的,所以类方法中没有分配空间存放类成员。

时间: 2024-10-21 12:00:53

从汇编学习c++ 之 类的方法调用的相关文章

python学习:扩展类的方法

一:先看一段小程序 <span style="font-size:18px;"><strong>class person: def __init__(self): print "new person" self.name = "lyl" def setName(self,name): self.name = name def printName(self): print self.name p = person(); p.

JVM学习笔记(二)--方法调用之静态分配和动态分配

本篇文章从JVM的角度来理解Java学习中经常提到的重载和重写. 方法调用:方法调用不等同于方法执行,在Java虚拟机中,方法调用仅仅是为了确定调用哪个版本的方法.方法调用分为解析调用和分派.解析调用一定是静态的,而分派可以是静态的,也可以是动态的.我们这里只介绍分派中的静态分配和动态分配. 静态分配:所有依赖静态类型来定位方法执行版本的分派动作称为静态分配. 下面看个例子,顺便来猜一下结果(面试中经常遇到): 1 class Human { 2 3 } 4 5 class Man extend

Java学习笔记之RMI远程方法调用

RMI 应用通常有两个分开的程序组成,一个服务端程序和一个客户端程序.一个典型的服务端程序创建一些远程对象,使得对这些远程对象的引用可以被访问,等待客户端调用这些远程对象提供的方法.一个典型的客户端程序获取远程引用,指向一个或者多个服务端上的远程对象,然后调用这些远程对象所提供的方法.通常我们称这为分布式对象应用程序. 3.1 RMI的工作方式 分布式对象应用程序需要做的事情: l 查找(定位)远程对象. 应用程序可以使用各种不同的机制取得远程对象的引用.比如应用程序可以通过 RMI 提供的简单

Struts2学习第七课 动态方法调用

动态方法调用:通过url动态调用Action中的方法. action声明: <package name="struts-app2" namespace="/" extends="struts-default"> <action name="Product" class="org.simpleit.app.Product"> </package> URI: --/strut

关于一个类中方法调用

大家都知道:对象是对客观事物的抽象,类是对对象的抽象,对象是类的实例. 在类中来调用方法,不过调用方法也有种种的情况. 在同一个类中的两个方法相互调用; 1.如果两个方法都是普通方法,那么可以直接用 public void eat(){ System.out.println("内容1"); sleep(); } public void sleep(){ System.out.println("内容2"); } 2.如果两个方法都是静态方法,那么可以直接用 publi

JAVA类的方法调用

一.类的分类: 1.普通类 2.抽象类(含有抽象方法的类) 3.静态类(不需要实例化,就可以使用的类) 二.方法的分类: 1.私有方法(只有类的内部才可以访问的方法) 2.保护方法(只有类的内部和该类的子类可以访问的方法) 3.共有方法(无论内部或外部均可访问的方法) 4.静态方法(可以不实例话对象,通过类名.方法就可以调用的方法) 5.抽象方法(只有方法的签名而没有实现的方法) 三.方法的调用: 1.普通类:实例化一个该类的对象,然后通过对像访问.例如: class A { public vo

SpringMVC学习(七)——Controller类的方法返回值

本文所有案例代码的编写均建立在前文SpringMVC学习(六)——SpringMVC高级参数绑定与@RequestMapping注解的案例基础之上,因此希望读者能仔细阅读这篇文章. 返回ModelAndView Controller类方法中定义ModelAndView对象并返回,对象中可添加model数据.指定view.之前我就已讲过,在此并不过多赘述. 返回void 在Controller类方法形参上可以定义request和response,使用request或response指定响应结果:

关于一个类中方法调用情况

一.如果两个方法都是普通方法,那么可以直接用方法名调用 public void Happy() { System.out.println("play!") Sleep(); } public void Play() { System.out.println("Sleep!!"); } } } 二.如果两个方法都是静态方法,那么可以直接用方法名调用 public static void Play() { System.out.prinltn("Hello!&

类内方法调用自身

package ww; public class helloword { public static void main(String[] args) { // TODO Auto-generated method stub helloword hh=new helloword(); hh.s(); //s(); helloword.s(); } public static void s(){ System.out.println("123"); }} //静态方法才可以调用静态方法.