三种call解释(二): 代码解释

本文深入探讨了C++中不同的函数调用约定,包括_cdecl、_stdcall和__declspec(naked)。通过具体的代码示例,展示了这些调用约定在实际编程中的应用,以及它们如何影响函数的参数传递和栈清理。
#include <iostream>
#include <Windows.h>

using namespace std;


void _cdecl test111(int num)
{
	printf("num=%d\n", num);
}

void _stdcall test222(int num)
{
	printf("num=%d\n", num);
}

void __declspec(naked) test333(int num)
{
	_asm{
		push ebp
		mov  ebp,esp
	}

	printf("num=%d\n", num);

	_asm{
		mov  ebp,esp
		pop  ebp
		retn 
	}
}

void _cdecl test(int num)
{
	printf("_cdecl num=%d\n", num);
	//////  EIP的值不允许通过MOV指令来修改,可以通过PE结构修改;

	_asm{
		push num
		call test111     // 调用cdcall的方法;
		add ESP,0x4
	}

	int xxx = 0;

	_asm{
		push num
		call test333     // 调用naked call的方法;
		add ESP,0x4
	}

	_asm{	
		push num          // 调用stdcall的方法;
		call test222
	}

	int xxx2 = 1;

}

void  _stdcall test1(int num)
{
	printf("_stdcall num=%d\n", num);

	_asm{
		push num
			call test111     // 调用cdcall的方法;
			add ESP,0x4
	}

	int xxx = 0;

	_asm{
		push num
			call test333     // 调用naked call的方法;
			add ESP,0x4
	}

	_asm{	
		push num          // 调用stdcall的方法;
			call test222
	}

	int xxx2 = 1;
}


int main()
{

  int num = 20;

  _asm{
	mov eax,0
	mov eax,0
	mov eax,0
  }

  test(num);     //  _cdecl
  test1(num);     //  _cdecl

  _asm{
	  mov eax,0
		  mov eax,0
		  mov eax,0
  }
  test111(num);  //  _cdecl
  _asm{
	  mov eax,0
		  mov eax,0
		  mov eax,0
  }
  test222(num);  //  _stdcall
  _asm{
	  mov eax,0
		  mov eax,0
		  mov eax,0
  }

  test333(num);

  printf("num=%d\n", num);

//  MessageBoxA(0, 0, 0, 0);

//  getchar();


  return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值