6
2008-10-24 02:37
很好,这种学习精神很好,梁肇新就特别”鼓吹“程序员从汇编一级,从机器的角度看待程序。
好,我来说说你不明白的地方。
直接写注释中了,自己看吧。我就是在你加问号的地方写了。
另外你原来的不太恰当的注释我给你更正了。
好好学习,祝你进步。希望对方你有帮助。
1: #include "stdio.h"
2: void main()
3: {
0040D6F0 55 push ebp //保存堆栈指针
0040D6F1 8B EC mov ebp,esp //这两句是标准的函数入口点,是作用是建立一个用ebp作访问基址的标准堆栈帧结构。
//如果索引值为正,访问的是函数的参数,为负为局部变量,如 ss:[ebp + 8]就是访问函数的第一个参数
0040D6F3 83 EC 48 sub esp,48h //这个是在堆栈帧上为局部变量分配空间,可以看到编译器共分配了0x48个字节给局部变量(包括保存中间结果的临时变量)
0040D6F6 53 push ebx
0040D6F7 56 push esi
0040D6F8 57 push edi //保护一些寄存器
0040D6F9 8D 7D B8 lea edi,[ebp-48h] //edi指向当前堆栈顶
0040D6FC B9 12 00 00 00 mov ecx,12h //这是全部局部变量所占用的存储空间,以DWORD为单位,所以是0x48 / 4 = 0x12
0040D701 B8 CCCCCCCC mov eax,0CCCCCCCCh //这是将堆栈中局部变量存储区全部用0xCC填充,这种初始化是DEBUG模式下编译才会生成的
//至于为什么用0xCC,这个说过很多次了,因为0xCC是int3指令的机器码
//这样就可以在程序有漏洞,比如因溢出而”飞“到数据区执行时就会触发调试异常
//而调试器可以捕获该异常从而帮助程序员除错。
0040D706 F3 AB rep stos dword ptr [edi] // 上面已经说过了,用调试模式的值初始化局部变量
4: int* x;
5: int m;
6: x=&m;
0040D708 8D 45 F8 lea eax,[ebp-8]
0040D70B 89 45 FC mov dword ptr [ebp-4],eax
7: }
0040D70E 5F pop edi
0040D70F 5E pop esi
0040D710 5B pop ebx
0040D711 8B E5 mov esp,ebp
0040D713 5D pop ebp
0040D714 C3 ret
#####################################
源程序: #include "stdio.h"
void main()
{
int* x;
int m;
x=&m;
}