- 帖子
- 3852
- 积分
- 13044
- 威望
- 16780
- 金钱
- 36761
- 在线时间
- 1139 小时
|
大家好,今天我们来讲解一下栈的延伸,“堆栈”。算是把昨天的整个理论基础概念,给大家讲解下。
运行时栈(RUNTIME stack)--我们通常称为“堆栈”,这是由我们cpu硬件直接支持的,也是实现过程的调用和过程返回机制的基本组成部分。
不知道大家是否知道RTL是什么意思。如果学过程序的人都应该知道这个就是运行时库,它是我们程序运行时必须的库。例如我们BCB中的VCL RTL。我们的bcb程序必须依赖vcl的运行时库。
堆栈是由我们cpu直接管理的内存区域(也可以形容其数组,因为它的确有相似数组的特性)。其实大家昨天已经感受到了堆栈的特性。就是“后进先出,向下扩展”的特性。
堆栈的用途:
1.寄存器在用做多种用途的时候,堆栈可以方便的作为临时保存区域。在寄存器使用完毕后,可恢复其原始值。
2.调用子程序的时候放过程返回的地址。
3.子程序的局部变量在堆栈中创建,结束时,变量丢弃
4.调用子程序的时候,可以通过堆栈传输输入值。
昨天已经讲解了push pop指令。
push 压栈 相应的esp寄存器-4,如果是实模式-2
pop 出栈 相应的esp寄存器+4,如果是实模式+2
从以上我们就可以认识到堆栈的向下扩展的特性。因为压入堆栈,相应的esp减少,那么表示我们的堆栈往下扩展。
今天还要介绍两个与堆栈相关的汇编指令。pushad popad pusha popa
pushad是将我们所有的32位通用寄存器压入堆栈,popad则是将我们所有的32位通用寄存器按压入时候相反的顺序取出堆栈。一般用于子程序保存但前的环境,例如我们的子程序需要修改一些寄存器的值,我们就可以用这个先保存,等子程序结束后,将其所有的备份的寄存器值在恢复,这样就不会破坏其他子程序运行的情况。
这两个指令,在免杀方面比较常用。相信看过免杀课程动态恢复数据段ASCII字符串的朋友都应该知道。
pusha是将我们所有的16位通用寄存器压入堆栈,popa同理是将我们所有的16通用寄存器取出堆栈。
由于今天主要是为了把上节课程做一个补充的,所有的内容就这么多。堆栈到这里我们基本就讲解完了。其实我们只要理解了它的特性即可。。
小作业:
1. push指令是否能使用立即数。
2. pushad , popad 、pusha popa都是将哪些寄存器压入堆栈。分别列举。
3. 举出一个例子来描述堆栈“后进先出,向下扩展”的特性,说明自己的观点。。 |
|