本帖最后由 seai 于 2011-10-23 23:47:56 编辑

解决方案 »

  1.   

    我想出来一些需要运行时动态生成code的程序,其他的不会需要在栈里面放指令
      

  2.   

    堆栈中有数据data,也有代码code
    你从哪里知道的
      

  3.   

    上面从网上google来的代码就有提到啊:“堆栈也用于给函数中使用的局部变量动态分配空间, 同样给函数传递参数和函数返回值也要用到堆栈.”另外,我自己的理解也是一直认为:发生函数调用时,操作系统将保存现场,也就是将调用参数、返回地址保存起来。保存方式就是压入栈中,调用完成后返回的操作,其实就是将返回地址从栈中推出来。当然,如果是我理解错了,那么我来这来提问就是期望弄清这相关问题的。请大牛赐教。谢谢!
      

  4.   

    http://www.cnblogs.com/huangpeng/archive/2009/09/05/1560901.html还找了一个网友写的函数调用过程的文章看看
      

  5.   

    后知后觉的人看了介绍,感觉像exe和com的区别。
      

  6.   

    堆栈也用于给函数中使用的局部变量动态分配空间, 同样给函数传递参数和函数返回值也要用到堆栈这些都是data,而不是用于执行的code
      

  7.   

    没错,一般程序是不会在堆栈里放code的。
    像比如执行函数或中断,call、int、ret等指令都是将地址信息保存在堆栈里,但是这些都是data,并不是被执行的。C语言传递函数也无需再里面放可执行的东西。比如到函数返回,直接执行ret指令(注意这指令在程序的代码里的,而非堆栈),它直接按照需要将地址读到CS:IP里。返回以后,清除堆栈也只是简单的SP寄存器操作罢了,没有任何需要执行堆栈内代码的必要。
    所以系统只需要简单的把堆栈所在的内存页面设置为NX不可执行就OK了。至于那些特殊的程序,比如加密的程序,要么根据需要修改代码,要么可以要求用户关闭DEP,当然这个需要修改BOOT.INI并重新启动才行。
      

  8.   

    楼上说的这位还是挺好理解的,不过你提到的“函数返回,直接执行ret指令(注意这指令在程序的代码里的,而非堆栈)”,我找到另一篇文章,其中一段说:      具体来说,从内存的角度看,函数h调用f时,Stack是按下面步骤发生变化的:
     实参按照从右向左的顺序一个一个进入stack中。
    函数调用指令之后的“下一条指令地址”进入stack中。
    函数f中的局部变量加入到stack中。
    函数f中的局部变量从Stack中弹出。
    “下一条指令地址”从stack中弱出,流入程序计数器寄存器IP中。
    寄存器AX/EAX/RAX中的值流入到stack中h的局部变量(或者全局变量等)中。
    调用函数f时的实参从stack中弹出。关于这如何理解?