函数栈桢概念_函数与栈帧的概念-程序员宅基地

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

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

智能推荐

典型计算机的性能分析,计算机系统性能测试与分析概论.ppt-程序员宅基地

文章浏览阅读233次。《计算机系统性能测试与分析概论.ppt》由会员分享,可在线阅读,更多相关《计算机系统性能测试与分析概论.ppt(59页珍藏版)》请在人人文库网上搜索。1、a,1,计算机系统性能测试陈文光清华大学计算机系,a,2,为什么要学这本门课,组装一台电脑 关心哪些指标? 处理器主频 内存大小 如何评价一个计算机系统的性能,选哪些程序评测? 都测试哪些值? 这些值如何汇总? 这些值真的能够反映计算机系统的性能..._计算机系统性能评价 陈文光

Leetcode错误:control reaches end of non-void function [-Werror=return-type]-程序员宅基地

文章浏览阅读2.9k次,点赞2次,收藏3次。leecode错误:control reaches end of non-void function [-Werror=return-type]_ontrol reaches end of non-void function [-werror=return-type]

Android之自定义实现BaseAdapter(通用适配器四)_关于baseadapter自定义适配器-程序员宅基地

文章浏览阅读2.8k次。Android之自定义实现BaseAdapter(通用适配器四)最近又学习到了一种自定义通用适配器的方法,刚好可以结合前面的一起来写一下,接下来先看代码吧。CommonAdapter.javapublic abstract class CommonAdapter extends BaseAdapter { //上下_关于baseadapter自定义适配器

IDEA中Maven项目转换为Gradle的方法_idea maven改为gradle-程序员宅基地

文章浏览阅读4.7k次。今天一个新项目突然用的不是Maven而是Gradle但是下载完成后发现依旧是maven的格式,于是查了下资料修改完成。settings-->Gradle根据需求配置,没有Gradle的可以去这个地址下载http://services.gradle.org/distributions/下载all结尾的如果右边弹框没有的标签可以去view-->Tool Windows 点击..._idea maven改为gradle

编写一个函数,输入一行字符,将此字符串中最长的单词输出。 输入仅一行,多个单词,每个单词间用一个空格隔开。_输入一行字符,将此字符串中最长的单词输出。单词之间用空格分开。提示:长度相同的-程序员宅基地

文章浏览阅读7.8k次,点赞6次,收藏8次。#include&lt;stdio.h&gt;#include&lt;string.h&gt;void main(){int i,j=0,k;char a[100],b[100]={"\0"},c[100];//这里的b数组全部初始化为结束符\0gets(a);for(i=0;i&lt;=strlen(a);i++){if(a[i]’ ’ || a[i]’\0’)//判定a如果是..._输入一行字符,将此字符串中最长的单词输出。单词之间用空格分开。提示:长度相同的

module_platform_driver宏解析_module platform driver-程序员宅基地

文章浏览阅读792次。转自http://blog.csdn.net/richu123/article/details/51331081该函数实际是一个宏,它在include/Linux/platform_device.h中定义如下:宏定义中对应3个参数:1个是结构体,另外两个是函数,分别用于注册和注销结构体。[cpp] view plain copy _module platform driver

随便推点

WPF 给容器加边框_stackpanel 边框-程序员宅基地

文章浏览阅读8.1k次,点赞2次,收藏3次。WPF 中不时所有控件都有Border边框属性,像容器就没有这个属性,那么如何给容器加边框呢,WPF中Border可以当做一个控件使用如下文给StackPanel内加Border控件 <StackPanel Name="panel" Grid.Column="0"> <Border BorderBrush="{DynamicResource {x:Static..._stackpanel 边框

las文件读写_pcl io loadlasfile-程序员宅基地

文章浏览阅读598次。读取有一点误差#include <pcl/visualization/cloud_viewer.h>#include <iostream>//标准C++库中的输入输出类相关头文件。#include <pcl/io/io.h>#include <pcl/io/pcd_io.h>//pcd 读写类相关的头文件。#include <pcl/..._pcl io loadlasfile

usbcamera拔掉设备崩溃_uscamera拔掉崩溃-程序员宅基地

文章浏览阅读848次。崩溃堆栈如下:解决办法:_uscamera拔掉崩溃

nacos启动失败问题解决_error creating bean with name 'asyncnotifyservice'-程序员宅基地

文章浏览阅读1.6w次,点赞15次,收藏18次。此报错是数据库配置问题,检查数据库地址、端口、数据库、账号、密码是否正确,同时确保数据库允许远程连接。登录mysql查询,localhost或者本机ip都是表示只允许本机连接数据库设置“%”允许所有主机连接让设置生效,重启MySQL也行允许./startup.sh -m cluster报以下错误查询jdk版本所未找到但是明明装了jdk也source /etc/profile 了,此时再让profile生效再查询会发现确实可以识别到jdk。_error creating bean with name 'asyncnotifyservice': unsatisfied dependency e

Tao Yu的论文(1) "Service Selection Algorithms for Web Services with End-to-end QoS Constraints (ISeB200...-程序员宅基地

文章浏览阅读62次。现在着重看web service replacement 方面的东西。部分转载自玉泉老博的博客。(受玉泉老博博客的启示,也准备在这里记录所看的东西,一是整理,二是督促)Yu Tao个人主页: http://link.ece.uci.edu/tyu/index.html本科就读于成都电子科技大学(1995), 硕士是北邮(1998), PhD在University of California, ..._yu t, zhang y, lin kj (2007) efficient algorithms for web services selection

java GIF拆分和压缩处理_import com.madgag.gif.fmsware.animatedgifencoder-程序员宅基地

文章浏览阅读2k次。一、依赖包:<dependency> <groupId>net.coobird</groupId> <artifactId>thumbnailator</artifactId> <version>0.4.8</version></dependency><dependency> <groupId>com.madgag</groupId>_import com.madgag.gif.fmsware.animatedgifencoder

推荐文章

热门文章

相关标签