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;
}
文章浏览阅读233次。《计算机系统性能测试与分析概论.ppt》由会员分享,可在线阅读,更多相关《计算机系统性能测试与分析概论.ppt(59页珍藏版)》请在人人文库网上搜索。1、a,1,计算机系统性能测试陈文光清华大学计算机系,a,2,为什么要学这本门课,组装一台电脑 关心哪些指标? 处理器主频 内存大小 如何评价一个计算机系统的性能,选哪些程序评测? 都测试哪些值? 这些值如何汇总? 这些值真的能够反映计算机系统的性能..._计算机系统性能评价 陈文光
文章浏览阅读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]
文章浏览阅读2.8k次。Android之自定义实现BaseAdapter(通用适配器四)最近又学习到了一种自定义通用适配器的方法,刚好可以结合前面的一起来写一下,接下来先看代码吧。CommonAdapter.javapublic abstract class CommonAdapter extends BaseAdapter { //上下_关于baseadapter自定义适配器
文章浏览阅读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<stdio.h>#include<string.h>void main(){int i,j=0,k;char a[100],b[100]={"\0"},c[100];//这里的b数组全部初始化为结束符\0gets(a);for(i=0;i<=strlen(a);i++){if(a[i]’ ’ || a[i]’\0’)//判定a如果是..._输入一行字符,将此字符串中最长的单词输出。单词之间用空格分开。提示:长度相同的
文章浏览阅读792次。转自http://blog.csdn.net/richu123/article/details/51331081该函数实际是一个宏,它在include/Linux/platform_device.h中定义如下:宏定义中对应3个参数:1个是结构体,另外两个是函数,分别用于注册和注销结构体。[cpp] view plain copy _module platform driver
文章浏览阅读8.1k次,点赞2次,收藏3次。WPF 中不时所有控件都有Border边框属性,像容器就没有这个属性,那么如何给容器加边框呢,WPF中Border可以当做一个控件使用如下文给StackPanel内加Border控件 <StackPanel Name="panel" Grid.Column="0"> <Border BorderBrush="{DynamicResource {x:Static..._stackpanel 边框
文章浏览阅读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
文章浏览阅读848次。崩溃堆栈如下:解决办法:_uscamera拔掉崩溃
文章浏览阅读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
文章浏览阅读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
文章浏览阅读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