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;
}
使用方法: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的技术栈用这张图概况(见附件).图片来源 IONIC 实战[url]http://baike.baidu.com/link?url=FycR4W5H5p9K5Ef67sOXGDECwBpfxooHdX6xda94YLVKoA5dE66OPOMhthffjloAKYSCqNvCXtab-guUf8S4eBA2NXJcRbEEUxdKWG02I0Lq88VlEH9USlZfKT_...
本文实例讲述了PHP判断是否微信访问的方法。分享给大家供大家参考,具体如下:在开发中有时需要禁止或者仅允许微信浏览器进行访问,则此时就需要对微信浏览器访问进行判断,本篇博文讲述如何判断是否是微信访问。/*** =======================================* Created by ZHIHUA·WEI.* Author: ZHIHUA·WEI* Date: 2018...
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
安装pyinstaller 打开cmd命令窗口,输入pyinstaller安装 pip install pyinstaller 若出现如下图所示的无法连接HTTPS的问题请参考文章 成功解决win10下 Can’t connect to HTTPS URL because the SSL module is not available_一顿吃不饱的博客-程序员宅基地 是否安装成功检查 pip list ...
这是一道朋友在群里发的一道题,我之前不是很懂柯里化,就自己试着写了一下,不知道算不算柯里化,望指教~下面是题目: function curry() { // your code..... } ================================ //写好之后一下代码可以正常运行...
数组运算创建两个随机数组加减乘除矩阵运算创建矩阵矩阵加减(行列相同)矩阵乘法(前行等于后列)
这个表格是从android sdk文档里摘出来的,简单看一下说明就明白是什么意思了。下面我们回到我们的主题上来:怎样获取图片的大小?思路很简单:首先我们把这个图片转成Bitmap,然后再利用Bitmap的getWidth()和getHeight()方法就可以取到图片的宽高了。新问题又来了,在通过BitmapFactory.decodeFile(String path)方法将
前言新鲜面筋出炉了!一直都挺喜欢京东这家公司的,于是一边复习,一边看京东的招聘信息。我是在7月25日投递的简历,投出去后等了三天,一直没有收到回音。本来以为已经石沉大海了的,没想到三天后收到了信息。因为目标公司不在本地,我当时还在乡下,网不好,所以整个面试节奏都往后推了一下,后面约了8月6日的笔试。后面,一切顺利进行,11号上午短信+邮件通知12号下午15.30电话面试。这里要说一下,给我面试的面试官口音是正宗川普,好几次我都没听清,让面试官重复了好几次问题,还好面试官有耐心hhh。下面,我记
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小记分类以攻击方向来区分的话网络基于大量的Flood耗尽目标网络带宽资源Syn Flood,发送大量伪造的 TCP 连接请求,从而使得被攻击方资源耗尽(CPU 满负载或内存不足)的攻击方式 。 用户向服务器发送报文后突然死机或掉线,那么服务器在发出应答报文后就无法收到客户端的确认报文(第三次握手无法完成),这时服务器端一般会重试并等待一段时间(至少 30s)后再丢弃这个未完成的连接ICMP Flood,Connection Flood利用真实的 IP 地址向服务
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){