函数栈桢概念_小蚂蚁_CrkRes的博客-程序员宅基地

技术标签: 汇编  汇编语言  栈桢  

stack frame 栈帧 (激活记录)

1.先要保护现场

2.将参数按照调用约定放在被运行栈帧上,这样这个栈帧的栈顶指针就会发生改变

3.如果有必要,调用函数会配置一个栈指针,保存调用方希望保持不变的内容(寄存器值)

4.被调用函数为它可能需要的任何局部变量分配空间,需要栈帧栈顶向上(-操作)开辟地方

5.被调用函数返回值存放在EAX或者存放在可以立即被调用到的地方

6.一旦函数完成其他操作,任何局部变量都释放了

7.调用地方如果重新获得控制权,删除再栈中开辟的空间(+操作)

8.完成“序言(3,4)”“过程(5,6)”“尾声(6,7)”

 

C的调用约定_cdecl(参数从右向左依次入栈),清理方式:调用者清理

对于参数可变化的:printf("XXXXX");

 

VOID demo_cdecl(int w,int x,int y,int z)

asm

push z

push y

push w

push x

call demo(进入了函数,开始执行了。。。。。。)

add esp,16 4*sizeof(int)

汇编测试代码:

	ret = cdeclAdd(a, b);
00F51939  mov         eax,dword ptr [ebp-24h]   ;cdecl
00F5193C  push        eax  					    ;push b
00F5193D  mov         ecx,dword ptr [ebp-18h]   ;a
00F51940  push        ecx  						;push a
00F51941  call        cdeclAdd (0F5135Ch)  
00F51946  add         esp,8  					;调用者清理堆栈
00F51949  mov         dword ptr [ebp-30h],eax  
//cdecl
int __cdecl	cdeclAdd(int a, int b)
{
00F51800  push        ebp  
00F51801  mov         ebp,esp  
00F51803  sub         esp,0C0h  
00F51809  push        ebx  
00F5180A  push        esi  
00F5180B  push        edi  
00F5180C  lea         edi,[ebp-0C0h]  
00F51812  mov         ecx,30h  
00F51817  mov         eax,0CCCCCCCCh  
00F5181C  rep stos    dword ptr es:[edi]  
	return a + b;
00F5181E  mov         eax,dword ptr [a]  
00F51821  add         eax,dword ptr [b]  
}
00F51824  pop         edi  
00F51825  pop         esi  
00F51826  pop         ebx  
00F51827  mov         esp,ebp  
00F51829  pop         ebp  
00F5182A  ret  

标准调用_stdcall

VOID demo_stdcall(int w,int x,int y,int z)

push z

push y

push x

push w

call demo(进入了函数,开始执行了。。。。。。)

ret 16

	ret = stdAdd(a, b);							;stdcall
00F51929  mov         eax,dword ptr [ebp-24h]   ;b
00F5192C  push        eax  						;push b
00F5192D  mov         ecx,dword ptr [ebp-18h]   ;a
00F51930  push        ecx  						;push a
00F51931  call        stdAdd (0F5124Eh)  		
00F51936  mov         dword ptr [ebp-30h],eax  
// stdcall 
int __stdcall stdAdd(int a, int b)
{
00F51880  push        ebp  
00F51881  mov         ebp,esp  
00F51883  sub         esp,0C0h  
00F51889  push        ebx  
00F5188A  push        esi  
00F5188B  push        edi  
00F5188C  lea         edi,[ebp-0C0h]  
00F51892  mov         ecx,30h  
00F51897  mov         eax,0CCCCCCCCh  
00F5189C  rep stos    dword ptr es:[edi]  
	return a + b;
00F5189E  mov         eax,dword ptr [a]  
00F518A1  add         eax,dword ptr [b]  
}
00F518A4  pop         edi  
00F518A5  pop         esi  
00F518A6  pop         ebx  
00F518A7  mov         esp,ebp  
00F518A9  pop         ebp  
00F518AA  ret         8  

快速调用_fastcall

VOID demo_fastcall(int w,int x,int y,int z)

前两个(ECX=W,edx=x)参数将被分配给ECX,EDX

剩下的都被按照_stdcall调用约定

ret 8

	ret = fastAdd(a, b);
00F5194C  mov         edx,dword ptr [ebp-24h]   ;mov edx,b
00F5194F  mov         ecx,dword ptr [ebp-18h]   ;mov ecx,a
00F51952  call        fastAdd (0F511EAh)  
00F51957  mov         dword ptr [ebp-30h],eax  
//fastcall
int __fastcall fastAdd(int a, int b)
{
00F51840  push        ebp  
00F51841  mov         ebp,esp  
00F51843  sub         esp,0D8h  
00F51849  push        ebx  
00F5184A  push        esi  
00F5184B  push        edi  
00F5184C  push        ecx  
00F5184D  lea         edi,[ebp-0D8h]  
00F51853  mov         ecx,36h  
00F51858  mov         eax,0CCCCCCCCh  
00F5185D  rep stos    dword ptr es:[edi]  
00F5185F  pop         ecx  
00F51860  mov         dword ptr [ebp-14h],edx  
00F51863  mov         dword ptr [ebp-8],ecx  
	return a + b;
00F51866  mov         eax,dword ptr [a]  
00F51869  add         eax,dword ptr [b]  
}
00F5186C  pop         edi  
00F5186D  pop         esi  
00F5186E  pop         ebx  
00F5186F  mov         esp,ebp  
00F51871  pop         ebp  
00F51872  ret  

C++调用约定

使用this指针

VC提供了 thiscall调用,将this传递给而ecx

GC++中被当做静态,存放在栈顶

ret =tt.add(a, b);
00F5195A  mov         eax,dword ptr [ebp-24h]  
00F5195D  push        eax  						;push b
00F5195E  mov         ecx,dword ptr [ebp-18h]  
00F51961  push        ecx  						;push a
00F51962  lea         ecx,[ebp-39h]  
00F51965  call        thiscallTest::add (0F511E5h)  
00F5196A  mov         dword ptr [ebp-30h],eax  
	int __thiscall add(int a, int b) {
00F517C0  push        ebp  
00F517C1  mov         ebp,esp  
00F517C3  sub         esp,0CCh  
00F517C9  push        ebx  
00F517CA  push        esi  
00F517CB  push        edi  
00F517CC  push        ecx  
00F517CD  lea         edi,[ebp-0CCh]  
00F517D3  mov         ecx,33h  
00F517D8  mov         eax,0CCCCCCCCh  
00F517DD  rep stos    dword ptr es:[edi]  
00F517DF  pop         ecx  
00F517E0  mov         dword ptr [ebp-8],ecx  
		return a + b;
00F517E3  mov         eax,dword ptr [a]  
00F517E6  add         eax,dword ptr [b]  
	}
00F517E9  pop         edi  
00F517EA  pop         esi  
00F517EB  pop         ebx  
00F517EC  mov         esp,ebp  
00F517EE  pop         ebp  
00F517EF  ret         8  

测试代码:

// InvokeRules.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>

// stdcall 
int __stdcall stdAdd(int a, int b)
{
	return a + b;
}
//cdecl
int __cdecl	cdeclAdd(int a, int b)
{
	return a + b;
}
//fastcall
int __fastcall fastAdd(int a, int b)
{
	return a + b;
}
//thiscall
class thiscallTest
{
public:
	thiscallTest() {}
	~thiscallTest() {}
	int __thiscall add(int a, int b) {
		return a + b;
	}
	
};

int main()
{
	int a = 10, b = 20;
	int ret{ 0 };
	thiscallTest tt;
	__asm {
		mov eax,0x11111
	}
	ret = stdAdd(a, b);
	ret = cdeclAdd(a, b);
	ret = fastAdd(a, b);
	ret =tt.add(a, b);
	__asm {
		mov eax,0x11111
	}
    return 0;
}

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zang141588761/article/details/99966412

智能推荐

django读取数据到dataframe_呆萌的代Ma的博客-程序员宅基地_dataframe django

使用方法:import pandas as pddataframe = pd.DataFrame(Model类名.objects.values())示例比如一个model:class MyModel(models.Model): data1 = models.CharField(max_length=255) data2 = models.CharField(max_length=255) data3 = models.CharField(max_length=255

IONIC笔记恶补(2)_沧桑老沈的博客-程序员宅基地

关于IONIC的技术栈用这张图概况(见附件).图片来源 IONIC 实战[url]http://baike.baidu.com/link?url=FycR4W5H5p9K5Ef67sOXGDECwBpfxooHdX6xda94YLVKoA5dE66OPOMhthffjloAKYSCqNvCXtab-guUf8S4eBA2NXJcRbEEUxdKWG02I0Lq88VlEH9USlZfKT_...

php判断微信环境_PHP判断是否微信访问的方法示例_bosstha的博客-程序员宅基地

本文实例讲述了PHP判断是否微信访问的方法。分享给大家供大家参考,具体如下:在开发中有时需要禁止或者仅允许微信浏览器进行访问,则此时就需要对微信浏览器访问进行判断,本篇博文讲述如何判断是否是微信访问。/*** =======================================* Created by ZHIHUA·WEI.* Author: ZHIHUA·WEI* Date: 2018...

【leetcode 二叉树 C++ dfs】1022. Sum of Root To Leaf Binary Numbers_笨比master的博客-程序员宅基地

1022. Sum of Root To Leaf Binary Numbers/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : va

python3项目打包成exe可执行程序_樱花花的博客-程序员宅基地_python3打包成exe文件

安装pyinstaller 打开cmd命令窗口,输入pyinstaller安装 pip install pyinstaller 若出现如下图所示的无法连接HTTPS的问题请参考文章 成功解决win10下 Can’t connect to HTTPS URL because the SSL module is not available_一顿吃不饱的博客-程序员宅基地 是否安装成功检查 pip list ...

一道柯里化面试题_weixin_34082854的博客-程序员宅基地

这是一道朋友在群里发的一道题,我之前不是很懂柯里化,就自己试着写了一下,不知道算不算柯里化,望指教~下面是题目: function curry() { // your code..... } ================================ //写好之后一下代码可以正常运行...

随便推点

numpy——数组、矩阵运算_carry_1024的博客-程序员宅基地

数组运算创建两个随机数组加减乘除矩阵运算创建矩阵矩阵加减(行列相同)矩阵乘法(前行等于后列)

BitmapFactory.Options详解_丁丁d的博客-程序员宅基地

这个表格是从android sdk文档里摘出来的,简单看一下说明就明白是什么意思了。下面我们回到我们的主题上来:怎样获取图片的大小?思路很简单:首先我们把这个图片转成Bitmap,然后再利用Bitmap的getWidth()和getHeight()方法就可以取到图片的宽高了。新问题又来了,在通过BitmapFactory.decodeFile(String path)方法将

腾讯android面试题,大厂经典高频面试题体系化集合,面试总结_普通网友的博客-程序员宅基地_腾讯android面试题

前言新鲜面筋出炉了!一直都挺喜欢京东这家公司的,于是一边复习,一边看京东的招聘信息。我是在7月25日投递的简历,投出去后等了三天,一直没有收到回音。本来以为已经石沉大海了的,没想到三天后收到了信息。因为目标公司不在本地,我当时还在乡下,网不好,所以整个面试节奏都往后推了一下,后面约了8月6日的笔试。后面,一切顺利进行,11号上午短信+邮件通知12号下午15.30电话面试。这里要说一下,给我面试的面试官口音是正宗川普,好几次我都没听清,让面试官重复了好几次问题,还好面试官有耐心hhh。下面,我记

jpa一对多OneToMany关联查询;debug下lazy失效原因_好大的月亮的博客-程序员宅基地_jpa onetomany查询

jpa一对多实体类关联查询package com.xx.xx.settings.domain;import lombok.*;import lombok.experimental.Accessors;import javax.persistence.*;import java.io.Serializable;import java.util.ArrayList;import java.util.Date;import java.util.List;@Table(name = "con

DDOS小记_Amire0x的博客-程序员宅基地

DDOS小记分类以攻击方向来区分的话网络基于大量的Flood耗尽目标网络带宽资源Syn Flood,发送大量伪造的 TCP 连接请求,从而使得被攻击方资源耗尽(CPU 满负载或内存不足)的攻击方式 。 用户向服务器发送报文后突然死机或掉线,那么服务器在发出应答报文后就无法收到客户端的确认报文(第三次握手无法完成),这时服务器端一般会重试并等待一段时间(至少 30s)后再丢弃这个未完成的连接ICMP Flood,Connection Flood利用真实的 IP 地址向服务

YV12转Iplimage_qq76211822的博客-程序员宅基地

void HC_Out(char *pBuf, DWORD dwWidth, DWORD dwHeight){ if(!pBuf){ return; } IplImage* pImage_YV12 = cvCreateImageHeader(cvSize(dwWidth, dwHeight / 2 * 3), IPL_DEPTH_8U, 1); if (!pImage_YV12){

推荐文章

热门文章

相关标签