# 函数

# 定义

类型  函数名 (参数类型 参数名,)
{
//内容
}

# 裸函数

编译器不会自动编译(函数中不会有任何代码),通过__asm 可以写入汇编代码。一定记得写 ret,使函数执行后返回。

void _declspec(naked)/*设置为裸函数*/  hanshu()
{

	__asm//汇编代码指令
		{
				ret//汇编代码  返回
		}

}

# 实操(实现简单的功能)

在这里插入图片描述

void _declspec(naked)/*设置为裸函数*/  hanshu()
{

	__asm//汇编代码指令
		{
				//保留栈底
				push ebp
				//提升堆栈
				mov ebp,esp
				sub esp,0x40
				//保留现场
				push ebx
				push esi
				push edi
				//填充缓冲区
				mov esx,0xCCCCCCCC//CC==int 3 中断指令
				mov ecx,0x10
				lea edi,dword ptr ds:[ebp-0x40]//算出后传给edi
				rep stosd
					//rep 根据ecx决定执行次数
					// stosd 将eax的值存入edi指定的地址中,此时edi会自动加4个字节
				//函数功能
				mov eax,dword ptr ds:[ebp+0x8]
					//ebp+0x4 是保留的栈底的值
				add eax,dword ptr ds:[ebp+0xc]
				//恢复现场
				pop edi
				pop esi
				pop ebx
				//降低堆栈
				mov esp,ebp
				pop ebp
				ret//汇编代码  返回
		}

}

# 调用约定

void _cdecl/*设置调用约定*/  hanshu(int x,int y)
{
}

img

_cdecl: 默认方式,从右到左压入,函数外平衡堆栈
_stdcall:从右到左压入,函数内平衡堆栈

  	-sam
  	ret  8  
  	//8==esp+8

fastcall:从左到右压入,特点是快。但只有前两个分别压入 ecx、edx。其余的还需 push,流程类似于 stdcall。

# 数据类型 & 数据存储

三要素:
1. 存储数据的宽度
2. 存储数据的格式
3. 作用范围(作用域)

# 基本类型

# 整数类型:char short int long

char8bit1 字节byte
short16bit2 字节word
int32bit4 字节dword
long32bit4 字节

整数类型分为有符号(signed)和无符号(unsigned)。
1. 存储方式完全一致
2. 在做运算时需要注意

# 浮点类型

IEEE

# 数据存储

img

# 全局变量

写入时一般直接写到某固定地址的为全局变量,程序运行时就创建了

# 局部变量

写入时一般直接写到栈的偏移位置,函数运行时才会在堆栈中分配地址,

# 扩展

img

对于有符号和无符号的使用不同的扩展方式,保证数据真值正确。

# 结构体

# 注意点

1.struct(结构体),它等价于 int、char 等
2. 结构体之间可以相互调用,但不能调用自己,
3. 结构体在搭建的时候并不会分配空间,只有在调用的时候才会分配。
四:可以以套娃:比如一个调用 aa.bb.cc.dd.x(表示有四个结构体套娃)

# 重点

连续地址:
等宽 —— 数组
不等宽 —— 结构体

# sizeof

返回所占空间大小
可以是类型、变量、数组、结构体。

# 对齐问题

改变对齐字节个数

#pragma pack(x)//x可取:1、2、4、8
结构体{}
#pragma pack()

imgimg

img

# typedef

imgimgimg

img