0x01.什么是裸函数
void _declspec(naked)Plus()
{…}
上面的函数调用 编译器不执行
// test.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
//返回值的类型 函数的名(参数类型 参数名,参数类型 参数名)
void _declspec(naked)Plus()
{
}
void Plus1()
{
}
//程序入口
int main(int argc, char* argv[])
{
Plus(); // 当调用Plus1,编译器执行(生成ret);调用Plus ,编译器出错
return 0;
}
call 把下条指令压入堆栈,修改eip
使用裸函数要使用下列代码,可以返回
__asm
{
ret
}
局部变量在缓冲器,返回值在eax
0x02.调用约定
![这里写图片描述](http://img.blog.csdn.net/20170119212613057?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvRHJlYW1SRQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
http://www.cnblogs.com/this-543273659/archive/2012/03/04/2379587.html
a. ___cdecl
int __cdecl plus1(int x,int y)
{
return x+y;
}
004010E8 push 2
004010EA push 1
004010EC call @ILT+0(plus1) (00401005)
004010F1 add esp,8 //栈外平衡
24:
25: return 0;
004010F4 xor eax,eax
26: }
004010F6 pop edi
004010F7 pop esi
004010F8 pop ebx
004010F9 add esp,40h
004010FC cmp ebp,esp
004010FE call __chkesp (00401120)
00401103 mov esp,ebp
00401105 pop ebp
00401106 ret
b. __stdcall
int __stdcall plus2(int x,int y)
{
return x+y;
}
004010E8 push 2
004010EA push 1
004010EC call @ILT+10(plus2) (0040100f)
0040100F jmp plus2 (00401060)
00401060 push ebp
00401061 mov ebp,esp
00401063 sub esp,40h
00401066 push ebx
00401067 push esi
00401068 push edi
00401069 lea edi,[ebp-40h]
0040106C mov ecx,10h
00401071 mov eax,0CCCCCCCCh
00401076 rep stos dword ptr [edi]
13: return x+y;
00401078 mov eax,dword ptr [ebp+8]
0040107B add eax,dword ptr [ebp+0Ch]
14: }
0040107E pop edi
0040107F pop esi
00401080 pop ebx
00401081 mov esp,ebp
00401083 pop ebp
00401084 ret 8 //栈外平衡
c. __fascall
int main(int argc, char* argv[])
{
plus3(1,2,3,4);
return 0;
}
28: plus3(1,2,3,4);
0040D528 push 4
0040D52A push 3
0040D52C mov edx,2
0040D531 mov ecx,1
0040D536 call @ILT+20(plus3) (00401019)
00401019 jmp plus3 (004010d0)
004010D0 push ebp
004010D1 mov ebp,esp
004010D3 sub esp,48h
004010D6 push ebx
004010D7 push esi
004010D8 push edi
004010D9 push ecx
004010DA lea edi,[ebp-48h]
004010DD mov ecx,12h
004010E2 mov eax,0CCCCCCCCh
004010E7 rep stos dword ptr [edi]
004010E9 pop ecx
004010EA mov dword ptr [ebp-8],edx
004010ED mov dword ptr [ebp-4],ecx
24: return x+y+z+k;
004010F0 mov eax,dword ptr [ebp-4]
004010F3 add eax,dword ptr [ebp-8]
004010F6 add eax,dword ptr [ebp+8]
004010F9 add eax,dword ptr [ebp+0Ch]
25: }
004010FC pop edi
004010FD pop esi
004010FE pop ebx
004010FF mov esp,ebp
00401101 pop ebp
00401102 ret 8
0x04.数据类型
1.数据类型的三个要素:
a.存储数据的宽度
b.存储数据的格式
c.作用范围
2.整数类型: char short int long
char 8 1字节
short 16 2字节
int 32 4字节
long 32 4字节
3.类型转换 ---比较大小和数学运算
有符号与符号 在内存中存储一样 ,
jle jbe
4.float 存储方式
a.将这个实数绝对值转化成二进制
b.将这个二进制格式实数的小数点左移或右移n位,知道小数点移动到第一位有效数字
c.从小数点右边第一位开始输出二 三 位数字放入22到0位
8.25转成浮点存储
正数部分8转成二进制
8/2 = 4 0
4/2 = 2 0
2/2 = 1 0
1/2 = 0 1
小数部分0.25转成二进制
0.25*2 = 0.5 0
0.5 *2 = 1 1
8.25用二进制可表示1000.01
2.1000.01 ------> 1.00001 左移为1
3. 符号位1 指数部分8(第一位正负 后面是指数) 尾数部分23(左移后小数点的数)
0 10000010 0000100000000000000000
0100 0001 0000 0100 0000 0000 0000 0000
41010000
0.25
1.整数部分:0
小数部分
0.25*2 = 0.5 0
0.5*2 = 1.0 1
0.25转换成二进制:0.01
2.0.01 ——> 1.0 * 10^ -2 右移为0
0 01111101 00000000000000000000000
0011 1110 1000 0000 0000 0000 0000 0000
3F800000
“`