C语言02_数据类型

裸函数

C源码(.c) →【预处理】→【编译】→【汇编】→【链接】→可执行程序

  1. 预处理 (cpp):展开头文件、宏替换、删掉注释,生成 .i 文件(还是 C 语言文本)
  2. 编译 (cc1)C → 汇编 (.s)
  3. 汇编 (as):汇编 (.s) → 机器码目标文件 (.o/.obj)
  4. 链接 (ld):多个.o + 库 → exe/elf 可执行文件

因此在我们的程序成为可执行文件之前,先转化为汇编语言,我们看到的函数里面的那些代码都死编译器自己生成的,push ebp等等,裸函数是编译器完全不生成函数 prologue (序言) /epilogue (尾声),你必须手写全部汇编。

需要注意的是 裸函数不能为空 而且不能出现C格式的代码

void __declspec(naked) Function()

{

_asm

}

{

汇编内容

}

列举三个常用的裸函数框架

无参数无返回值的框架

void __declspec(naked) Function()  				
{				
	__asm			
	{			
		push ebp		
		mov ebp,esp		
		sub esp,0x40		
		push ebx		
		push esi		
		push edi		
		lea edi,dword ptr ds:[ebp-0x40]		
		mov eax,0xCCCCCCCC		
		mov ecx,0x10		
		rep stosd		
				
		pop edi		
		pop esi		
		pop ebx		
		mov esp,ebp		
		pop ebp		
				
		ret		
	}			
}				

有参数有返回值的函数框架

int __declspec(naked) Function(int x,int y)  					
	{					
		__asm				
		{				
			push ebp			
			mov ebp,esp			
			sub esp,0x40			
			push ebx			
			push esi			
			push edi			
			lea edi,dword ptr ds:[ebp-0x40]			
			mov eax,0xCCCCCCCC			
			mov ecx,0x10			
			rep stosd			
						
			mov eax,dword ptr ds:[ebp+8]			
			add eax,dword ptr ds:[ebp+0xC]			
						
			pop edi			
			pop esi			
			pop ebx			
			mov esp,ebp			
			pop ebp			
						
			ret			
		}				
	}					
				

带局部变量的函数框架

int __declspec(naked) Function(int x,int y)  					
{					
	__asm				
	{				
		push ebp			
		mov ebp,esp			
		sub esp,0x40			
		push ebx			
		push esi			
		push edi			
		lea edi,dword ptr ds:[ebp-0x40]			
		mov eax,0xCCCCCCCC			
		mov ecx,0x10			
		rep stosd			
		mov dword ptr ds:[ebp-4],2			
		mov dword ptr ds:[ebp-8],3			
					
		mov eax,dword ptr ds:[ebp+8]			
		add eax,dword ptr ds:[ebp+0xC]			
					
		pop edi			
		pop esi			
		pop ebx			
		mov esp,ebp			
		pop ebp			
					
		ret			
	}				
}					

裸函数作业

练习:						
						
1、用__declspec(naked)裸函数实现下面的功能						
						
练习目的:						
						
(1) 熟悉堆栈结构						
						
(2) 参数、局部变量的位置						
						
(3) 返回值存储的位置						
						
int plus(int x,int y,int z)					010101010	
{						
	int a = 2;					
	int b = 3;					
	int c = 4;					
	return x+y+z+a+b+c;					
}						
下面是作业内容
#include<stdio.h>
int plus1(int x, int y, int z)
{
	int a = 2;
	int b = 3;
	int c = 4;
	return a + b + c + x + y + z;

}
int _declspec(naked) plus(int x, int y, int z)//转换的裸函数
{
	_asm
	{
		push ebp;
		mov ebp,esp
		sub esp,0x40
		push ebx
		push esi
		push edi
		mov eax,0xcccccccc
		mov ecx,0x10
		lea edi,dword ptr ds:[ebp-0x40]
		rep stosd
		mov dword ptr ds:[ebp-4],2
		mov dword ptr ds : [ebp - 8] , 3
		mov dword ptr ds : [ebp - 0Xc] , 4
		//	核心计算功能
		mov eax,dword ptr ds:[ebp-4]//第一个变量赋值给eax
		add eax,dword ptr ds:[ebp - 8]//第一个变量赋值给eax
		add eax,dword ptr ds:[ebp - 0XC]//第一个变量赋值给eax
		add eax,dword ptr ds:[ebp+8]//第一个参数赋值给eax
		add eax,dword ptr ds:[ebp+0xC]//第一个参数赋值给
		add eax,dword ptr ds:[ebp+0x10]//第一个参数赋值给
		pop edi
		pop esi
		pop ebx
		mov esp,ebp
		pop ebp
		ret
	}
}
extern "C" void test()
{

}
int main()
{
	int res = plus(1, 2, 3);
	printf("%d", res);
}

调用约定

上一篇 C语言01_后半节
因特叁

因特叁管理员

动物世界

本月创作热力图

目录