实验环境为VS2015
#include <stdio.h>
void decodeOprand()
{
/*
00C91650 push ebp
00C91651 mov ebp,esp
00C91653 sub esp,0C0h // 默认提高堆栈的大小为C0h;在x86系统中,内存是小端存储方式
00C91659 push ebx
00C9165A push esi
00C9165B push edi
00C9165C lea edi,[ebp-0C0h]
00C91662 mov ecx,30h
00C91667 mov eax,0CCCCCCCCh // 填充为0CCCCCCCCh,防止中间出现问题,如果出现问题则可以及时的产生中断,以便调试器可以接收到中断
00C9166C rep stos dword ptr es:[edi]
*/
// 防止被和谐
// 00C9166E mov dword ptr [i],0
// 去掉 右键->显示符号名后可以看到
// 00C9166E mov dword ptr [ebp-8],0
// 可以证明i <=> ebp-8;即我们声明的变量符号i,在汇编中代表的是地址ebp-8;也可以看出来是栈变量;即局部变量为栈变量
// 第一个变量的起始地址为ebp-8;
// int i = 0;
// 00F41A75 mov dword ptr [ebp - 14h], 2
// 增长的幅度为 0x14h - 0x08h = 0Ch;
// int b = 2;
// int c = 3;
char a = 1;
// char d = 4;
// short b = 2;
int c = 3;
// short e = 5;
// 相同的差0Ch,不同之间差0Fh
// short和int之间是一样的,只是对地址的解释不一样
// short是将从[]地址解释为word大小;int是将从[]地址解释为dword大小
// 以有符号整数进行解释
// 在分析过程中其实无需知道到底是哪个,只需要知道每个内存单元的功能,以及怎么解释的即可
}
void decodePointer()
{
int nVar = 0x12345678;
int* pnVar = &nVar;
char* pcVar = (char*)&nVar;
short* psnVar = (short*)&nVar;
printf("%08x \r\n", *pnVar);
printf("%08x \r\n", *pcVar);
printf("%08x \r\n", *psnVar);
}
void decodePointerOperator()
{
// cVar 代表的是数组的第一个数据的首地址
// __cdecl调用约定,参数传递为从右到左;调用方负责清理堆栈
// 00834B48 mov byte ptr [ebp-10h],1
char cVar[5] = { 0x01,0x23,0x45,0x67,0x89 };
// 01194B5C lea eax,[ebp-10h]
// 01194B5F push eax
printf("%x\r\n", cVar);
int* pnVar = (int*)cVar;
char* pcVar = (char*)cVar;
short* psnVar = (short*)cVar;
/*
00C34B6E mov eax,dword ptr [ebp-1Ch]
00C34B71 add eax,4
00C34B74 mov dword ptr [ebp-1Ch],eax
00C34B77 mov eax,dword ptr [ebp-28h]
00C34B7A add eax,1
00C34B7D mov dword ptr [ebp-28h],eax
00C34B80 mov eax,dword ptr [ebp-34h]
00C34B83 add eax,2
00C34B86 mov dword ptr [ebp-34h],eax
*/
// 首地址 + sizeof(指针type) * n;
pnVar += 1;
pcVar += 1;
psnVar += 1;
// 每加一个*就是在这个指针的type上减掉一个星
int a = 1;
int* i = &a;
int** pI = &i;
int*** pPi = &pI;
int**** p = &pPi;
/*
01054C89 mov eax,dword ptr [ebp-70h]
// 下面是*的操作,有几句就是几颗*
01054C8C mov ecx,dword ptr [eax]
01054C8E mov edx,dword ptr [ecx]
01054C90 mov eax,dword ptr [edx]
01054C92 mov ecx,dword ptr [eax]
*/
printf("%x\r\n",****p);
// * 的运用:假设int**** p = (int****)&nVar; 那么***p == nVar;
}
void usePointer()
{
// 要修改被const限制的局部变量i
const int i = 10;
int* pnI = (int*)&i;
*pnI = 20;
// 在内存中其实已经改了,但是为什么输出的还是10呢
// 答案是常量传播,看反汇编即可明确
/*
008B4B64 push 0Ah
008B4B66 push 8B6C0Ch
008B4B6B call 008B1352
*/
// 经由常量传播,直接吧0Ah传递给了printf函数
printf("%d %d\r\n",i,*pnI);
}
int main()
{
decodeOprand();
decodePointer();
decodePointerOperator();
usePointer();
getchar();
return 0;
}