zoukankan      html  css  js  c++  java
  • ThisCall调用分析

    C++程序的成员函数默认使用的调用约定是thiscall,这种约定是把this指针放到ECX寄存器中.This调用协定也是要求被调用函数负责清理栈,因此不支持可变数时的参数,当我们在C++类中定义了可变数量参数的成员函数时,偏译器会自动改为使用C调用约定,当这种调用时,编译器会将所有参数压入栈中,再将this指针压入栈:

    关键两点:1.this时,是被调用函灵敏清理栈 2.如果可变参数,则使用C约定,由调用者来清理

    写个小demo测试:

    #include "stdafx.h"
    #include <stdio.h>
    enum MEAL {BREAKFAST, LUNCH, SUPPER};
    
    class Cat
    {
    public:
    	MEAL Fun0(MEAL i)
    	{
    		return i;		
    	}
    	char* Fun1(MEAL i, ...)
    	{
    		return 0;
    	}
    };
    
    
    int main(int argc, char* argv[])
    {
       
    	Cat cat;
    	cat.Fun0(BREAKFAST);
    	cat.Fun1(BREAKFAST, "meat", "beaf", "rice");
    
    	return 0;
    }

    0:000> x ThisCall!Cat::*
    00401060 ThisCall!Cat::Fun0 (MEAL)
    00401090 ThisCall!Cat::Fun1 (MEAL)
    0:000> x ThisCall!main
    00401000 ThisCall!main (int, char **)
    0:000> bp 00401000 
    
    先在main处下断点:

    ThisCall!main:
    00401000 55              push    ebp
    00401001 8bec            mov     ebp,esp
    00401003 83ec44          sub     esp,44h
    00401006 53              push    ebx
    00401007 56              push    esi
    00401008 57              push    edi
    00401009 8d7dbc          lea     edi,[ebp-44h]
    0040100c b911000000      mov     ecx,11h
    00401011 b8cccccccc      mov     eax,0CCCCCCCCh
    00401016 f3ab            rep stos dword ptr es:[edi]
    00401018 6a00            push    0//入值BREAKFAST
    0040101a 8d4dfc          lea     ecx,[ebp-4]//这地方明显ebp-4为Cat cat这个局部变量,也就是把this赋给ECX
    0040101d e83e000000      call    ThisCall!Cat::Fun0 (00401060)//Fun0后调用者不用清栈
    00401022 68fce04000      push    offset ThisCall!`string' (0040e0fc)
    00401027 68f4e04000      push    offset ThisCall!`string' (0040e0f4)
    0040102c 68ece04000      push    offset ThisCall!`string' (0040e0ec)
    00401031 6a00            push    0
    00401033 8d45fc          lea     eax,[ebp-4]
    00401036 50              push    eax
    00401037 e854000000      call    ThisCall!Cat::Fun1 (00401090)
    0040103c 83c414          add     esp,14h//Fun1后调用者需要清栈
    这样就看得很清楚了.


  • 相关阅读:
    Glide优化
    Java多线程知识点
    Android知识点
    Gradle的一些技巧和遇到的问题
    Python用Django写restful api接口
    Python写爬虫爬妹子
    用最简单的例子说明设计模式(三)之责任链、建造者、适配器、代理模式、享元模式
    【Python】扫描指定文件夹下特定后缀的文件
    【Python】生成多级树结构的xml文件
    【转】【Linux】安装pyinstaller
  • 原文地址:https://www.cnblogs.com/hgy413/p/3693423.html
Copyright © 2011-2022 走看看