Win32汇编(MASM32)技术笔记

Win32汇编(MASM32)技术笔记
 
2009-5-16

最近无意间开始学习汇编语言了以前涉猎过一些汇编书籍,但是当时功力不够,看得晕头转向的。现在开始学习,还是相对容易的。但因为没人知道,也是一步一步的摸索的很艰辛。
汇编作为一种低级语言,语法的运用固然不能像高级语言极富逻辑语义性,但他有他自己独特的特点
I、为什么要学汇编?
首先,汇编语言是低级语言,其实就是机器语言以一种别名的形式存在,其运行速度是不言而喻的。所以在对效率要求很高的程序中汇编能做到很好的优化
其实,现在找工作看的还是高级语言,是不是汇编就很少有用武之地啦?答案是否定的。现在的高级语言很注重封装性,如C++等提供了功能强大的类库,你不必知道这些功能是如何实现的只需要组织运用就行。而学习汇编就要了解比如一个程序具体是怎样在内存中运行的等等。了解这些更深层面的细节,能让你对高级语言的运用更加驾轻就熟。
而且,学习WIN32汇编能让你了解WINDOWS系统的运行细节,且能更深入的掌握WINDOWS下的编程思想。
废话不多说,切入正题。完成对汇编基础知识的学习,首先明白了函数调用细节与程序调用时的内存细节,这次笔记就这些做些总结:
II、程序运行的内存分配&函数调用&局部变量的申请释放&堆栈平衡
(技术报告可以当教程啦O(∩_∩)O哈哈~)
先用C语言代码举出简单的例子
Int var1;
Static int var2;
Int proc(int a)
{int c,d;
d=a;
return d;
}
Void main()
{int a,b;
Int *ptr,*str=”hello world”;
Ptr=malloc(4*sizeof(int));
a=2;
b=proc(a);
}
这就是一个简单的变量定义、内存申请、函数调用的简单例子。
一、程序运行时的内存管理
程序编译运行后在内存中的存储情况
栈区:定义的变量放在栈里面,如a,b是由编译器在栈上申请的空间(具体是怎么弄得,以后有待于研究编译原理)程序运行后会被系统自动释放
堆区:由用户自己申请分配的空间,如Ptr=malloc(4*sizeof(int)); 这一句是申请了4个整型变量空间。空间是在堆上的(虽然习惯说堆栈,但堆和栈其实是两个概念)而且需要用户自己释放。如果忘记释放便可能会造成内存泄露
全局区(静态区):全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后由系统释放。如例子中的 var1 var2
文字常量区:这里存放着程序所用到的字符串如例子中的”hello world\0”
代码区:程序编译后的指令会存到这里。EIP寄存器会逐条指向这里的指令地址。

二、函数调用、局部变量与堆栈的平衡
例子中b=proc(a);
汇编中的调用方式是
Push a
Call proc
Mov b,eax


其流程如下
1、Push a   :参数a被压入堆栈(指的是栈)中
2、Push 0003A0F2H   :call语句紧把调用proc过程(函数)处的地址压入堆栈(即返回地址假定为0003A0F2H 这就是代码区的一个地址)
3、Mov eip,0004A0FFH :程序跳转到proc过程的地址去运行
4、Push ebp   :保存ebp 后面会解释为什么要保存
5、Mov ebp,esp  :用ebp保存堆栈指针即esp
注:ebp解释为基址指针,其实我感觉应该理解为数据指针,他用来访问堆栈中的数据,但他是不变的,操作用ebp+或-x来访问,因此他可以用来保存esp原来的值用于最后恢复esp从而释放局部变量
Esp是堆栈指针,他一直指向栈顶会随着堆栈数据的增多而变化push 和pop指令操作的就是esp所指向的地址
6、sub,esp,8   :esp减少8 增加堆栈指针,因为堆栈数据在内存是从高地址向低地址排列的所以逻辑上可以看做增加堆栈指针,或抬高指针,相当于留出了8个字节的空位即两个int局部变量(C语言中的int结构其实就是DWORD 而DWORD是CPU有关的,他等于CPU的位宽,所以TC是DOS下的C所以他的DWORD(int)所占的位数和当时16位CPU一样是16 而VC是WIN32下的C因此他的DWORD(int)所占的位数和32位CPU一样是32  和操作系统的位数也有关系 )
7、mov DWORD ptr [ebp-4],ebp+8 :将参数a的数据给局部变量d,这里就是利用ebp来访问堆栈里面的数据
8、mov eax, DWORD ptr [ebp-4]  :将局部变量d作为返回值汇编中的返回值都是放在寄存器中eax的
9、mov esp,ebp :恢复堆栈指针相当于释放了局部变量因为esp相当与堆栈的边界,现在那两个局部变量已经在边界外所以不再是堆栈数据,被系统回收了。
10、Pop ebp :恢复ebp指针对应前面的保存。因为函数proc是main主函数调用的,而主函数中也需要ebp访问堆栈数据,因此在调用proc要进行“现场保护”,便于返回到主函数时恢复,以免引起错误
11、pop eip  :返回到调用proc过程的地方

以上就是一个函数调用的全部过程
其实WIN32汇编中不会这么麻烦这些编译器已经都帮你做好了你只管call就行局部变量用LOCAL宏返回用RET就OK了
但是这些是都是具体的细节,所以了解他们的意义不可小视,而这些正是我学习汇编语言的第一份收获

你可能感兴趣的:(Win32)