制造缓冲区溢出:  
    一个程序在内存中通常分为程序段,数据端和堆栈三部分。程序段里放着程 
序的机器码和只读数据。数据段放的是程序中的静态数据。动态数据则通过堆栈 
来存放。在内存中,它们的位置是: 
                          +------------------+  内存低端 
                          |       程序段     | 
                          |------------------| 
                          |       数据段     | 
                          |------------------| 
                          |        堆栈      | 
                          +------------------+  内存高端 
    当程序中发生函数调用时,计算机做如下操作:首先把参数压入堆栈;然后 
保存指令寄存器(IP)中的内容做为返回地址(RET);第三个放入堆栈的是基址寄 
存器(BP);然后把当前的栈指针(SP)拷贝到BP,做为新的基地址;最后为本地变 
量留出一定空间,把SP减去适当的数值。请问:
1、基址寄存器BP是做什么用的?
2、当函数调用时,BP中保存的是什么,为什么要入栈?
3、把当前的栈指针(SP)拷贝到BP,做为新的基地址,这句话是什么意思?
4、指令寄存器(IP)中的内容为要执行的下一条指令的地址,这个地址是否在程序段的地址空间内?

解决方案 »

  1.   

    1、通过BP来访问函数中的变量,如传入的参数。
    2、保存的是上一次的BP值啊
    3、函数中需要调整SP,相当于在堆栈中分配了控件,所以SP的值会丢失,把SP先保存到BP中,才能够正确的访问传入的参数等变量。
    4、地址空间在WIN32系统下不分段的(虽然存在着选择子的概念,但和以前不一样),所以IP地址指向4G中的任何一个地方都可以,只要IP指向的是可执行指令。注意:不一定就是你的代码,有可能是系统的,比如系统调用你的函数。PS:还有你上面的图,不一定正确。
      

  2.   

    1、基址寄存器BP是做什么用的?
    ==============================
    BP用来保存当前程序要用到的堆栈基址2、当函数调用时,BP中保存的是什么,为什么要入栈?
    ==============================
    函数内部申明的变量一般都在堆栈上,这些变量实际上是在虚拟地址连续的一个缓冲区上,这个缓冲区是堆栈的一部分,这个缓冲区的首地址在BP中,(堆栈的基地址在SS),BP指向的堆栈头部一般就是调用者传来的参数,然后下面的就是本函数中申明变量.
    ==============================
    3、把当前的栈指针(SP)拷贝到BP,做为新的基地址,这句话是什么意思?
    ==============================
    我上面已经解释清楚,你应该知道为什么要这样,4、指令寄存器(IP)中的内容为要执行的下一条指令的地址,这个地址是否在程序段的地址空间内?
    ==============================
    同 kvls
      

  3.   

    2 补充,调用新的函数时,函数要使用新的堆栈,同时要保存旧的堆栈首地址,(注意在统一进程中,这些新的堆栈和旧的堆栈事实上是同一个堆栈的不同区域内,即SS相同)因此应该保存BP供新的函数返回时恢复调用者堆栈基址BP,同时将新函数的堆栈基址传给BP最简单的方法是直接将SP传给BP,然后SP减去适当的数值意思就是给当前函数的堆栈分配一定大小的空间