3: int main() {
006A2010 push ebp
006A2011 mov ebp,esp
006A2013 sub esp,0CCh
006A2019 push ebx
006A201A push esi
006A201B push edi
006A201C lea edi,[ebp-0CCh]
006A2022 mov ecx,33h
006A2027 mov eax,0CCCCCCCCh
006A202C rep stos dword ptr es:[edi]
006A202E mov ecx,offset _05E82D75_大三下\大三下\test@cpp (06AE026h)
006A2033 call @__CheckForDebuggerJustMyCode@4 (06A1271h)
4: int i = 1;
006A2038 mov dword ptr [i],1
5: i++;
006A203F mov eax,dword ptr [i]
006A2042 add eax,1
006A2045 mov dword ptr [i],eax
6: ++i;
006A2048 mov eax,dword ptr [i]
006A204B add eax,1
006A204E mov dword ptr [i],eax
7: return 1;
006A2051 mov eax,1
8: }
006A2056 pop edi
006A2057 pop esi
006A2058 pop ebx
006A2059 add esp,0CCh
006A205F cmp ebp,esp
006A2061 call __RTC_CheckEsp (06A127Bh)
006A2066 mov esp,ebp
006A2068 pop ebp
006A2069 ret
--- 无源文件 -----------------------------------------------------------------------
006A206A int 3
006A206B int 3
-
push ebp首先是执行一个函数的必要步骤,在堆栈里面放入ebp,这是调用main函数之前的堆栈的栈底地址,用来在main函数结束之后恢复堆栈用的。
-
move ebp esp 然后把ebp=esp也就是把栈底放到现在的栈顶的地方来。
-
sub esp,0CCh 把esp减去0CC由于栈地址是向低地址扩展的,所以我们是把栈空间扩展0cc个bit
-
push ebx
push esi
push edi
保存一些寄存器,这些是可以在main函数里面使用到的,所以我们先保存起来,到时候main函数结束了,我们就把它恢复起来。 -
006A201C lea edi,[ebp-0CCh]
lea的意思是load effective address 把[ebp-0cch]里面的有效地址给了edi,也就是ebp-0cch赋值给了edi,需要注意的是edi作为一个特殊的 寄存器,在循环指令里面会递增,在循环指令里面ecx是默认的循环次数 -
006A2022 mov ecx,33h 设置循环次数33h是0cch的四分之一,因为我们的一次循环会赋值四个字节,也就是dword ptr双字
-
006A2027 mov eax,0CCCCCCCCh 这是我们循环里面需要赋的值也就是int 3中断的值,int3是一个指令int表示指令的名字,3是这条指令的参数,int 3这条指令就是一条中断的指令。
-
006A202C rep stos dword ptr es:[edi]
这里比较难理解,rep是重复之后指令的指令
stos是store into string指令,把eax的值放到地址为edi的内存上面去。接着edi会自增,ecx会减一,这样我们就可以把刚刚扩展堆栈的那些空内存赋值为int 3指令了,这样如果不小心运行到这就会中断。这里面dword ptr是双字指针的意思,代表着后面的这个东西是一个地址,es是段寄存器,[edi]是偏移量 -
006A202E mov ecx,offset _05E82D75_大三下\大三下\test@cpp (06AE026h) offset是取首地址的意思
-
006A2033 call @__CheckForDebuggerJustMyCode@4 (06A1271h) 不懂
-
4: int i = 1;
006A2038 mov dword ptr [i],1
5: i++;
006A203F mov eax,dword ptr [i]
006A2042 add eax,1
006A2045 mov dword ptr [i],eax
6: ++i;
006A2048 mov eax,dword ptr [i]
006A204B add eax,1
这里的i对应的代码是一样的
cout << i++;
0086203F mov eax,dword ptr [i]
00862042 mov dword ptr [ebp-0D0h],eax
00862048 mov ecx,dword ptr [i]
0086204B add ecx,1
0086204E mov dword ptr [i],ecx
00862051 mov esi,esp
00862053 mov edx,dword ptr [ebp-0D0h]
00862059 push edx
0086205A mov ecx,dword ptr [_imp_?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A (086D0C8h)]
00862060 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (086D0D0h)]
00862066 cmp esi,esp
00862068 call __RTC_CheckEsp (086127Bh)
7: cout << ++i;
0086206D mov eax,dword ptr [i]
00862070 add eax,1
00862073 mov dword ptr [i],eax
00862076 mov esi,esp
00862078 mov ecx,dword ptr [i]
0086207B push ecx
0086207C mov ecx,dword ptr [_imp_?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A (086D0C8h)]
00862082 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (086D0D0h)]
00862088 cmp esi,esp
0086208A call __RTC_CheckEsp (086127Bh)
8: return 1;
当我们把i输出的时候,我们发现,在将函数的变量压栈的时候,两者不一样,对于i++是吧从内存里面取出来的 值先放到栈里面,然后在把内存里面的值加一,然后函数调用的时候是拿栈里面的 值当做参数push进去栈的。
而++i是在把内存里面的值加一了之后就直接把该内存里面的值拿出来当做函数参数放到栈里面