首页
社区
课程
招聘
0day书中关于函数调用的一章,系统调用和 栈平衡问题~(急于求解,在这里也发一下:)
发表于: 2009-3-11 09:23 3904

0day书中关于函数调用的一章,系统调用和 栈平衡问题~(急于求解,在这里也发一下:)

2009-3-11 09:23
3904
问题1. 系统调用时也会发生和函数调用一样的压栈操作吗??
问题2.函数调用返回地址,这个地址应该返回给EIP寄存器吗?而且值应该是调用点处call指令的下一条指令地址吗?不应该再返回到call指令处吧
问题3. 栈平衡时,说其实只压入上一栈帧的EBP,上一栈帧的ESP可以通过栈平衡计算得到,如何平衡? (是不是应该有个地方记录当前栈帧的大小的寄存器,然后拿当前的ESP减去该寄存器的值就是上一栈帧的栈顶)

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 232
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
关注一下啊~
2009-3-11 17:13
0
雪    币: 2110
活跃值: (21)
能力值: (RANK:260 )
在线值:
发帖
回帖
粉丝
3
1.不管系统调用也好,还是一般的函数调用也好,只是某种形式的“控制转移”。而“调用”与“分支(或叫做跳转)”这两种*转移*,本质上的区别就是“调用”必有“返回”,因此需要某种途径保存返回地址。

在x86中,一般的过程调用,返回地址被直接压入堆栈。而系统调用有很多途径,对于int 0x2E方式的系统调用,CPU通过异常处理机制转到ring0的ISR处执行,硬件按照中断发生时的行为执行的对现场的保存动作,包括ring3的cs:eip压栈,ring3的ss:esp压栈,当然还有eflags压栈。对于sysenter的系统调用方式,根据手册描述,sysenter指令并不保存返回地址,但系统可以使用ring3堆栈上的返回地址(即从KiFastSystemCall返回的地址)来返回调用处。
在amd64上,手册中提到syscall指令,而我在调试运行在32位兼容模式下的程序时,发现系统调用是先call一个ring3的占位函数,然后直接一个far jmp进入内核了,应该是通过call gate了。

2.任何一本汇编语言的书里都会讲到,call指令执行的动作是把下一条指令的地址压入堆栈,然后转到目标地址去执行;而ret指令可以理解为pop eip,也就是把栈顶的值弹出,装入程序计数器。

3.函数调用栈帧的平衡是由程序自身维护的,硬件没有任何特殊的机制。而程序代码自己是知道使用了多少栈空间的。在函数返回之前,只需要将自己使用的局部空间释放,堆栈自然就平衡了。

实际上,“堆栈平衡”只是一种约定,或者说习惯,并不是规定,更没有硬件检查机制。只要你愿意,写的程序可以随意使用堆栈,或根本不使用堆栈,只要你自己清楚程序的执行流程就行。
2009-3-11 18:22
0
雪    币: 232
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
谢谢 ,受教了
2009-3-12 12:06
0
游客
登录 | 注册 方可回帖
返回
//