这段代码是为我的本科生OS课程编写的。我尝试在同一个new_sp堆栈上调用一个函数,然后返回到new_sp正在做的事情。它不工作,我甚至不确定如何调试它。建议或解决方案将是很好的。我试着读完了,如果有什么遗漏的,请告诉我。
注意:它是我们为这个类使用的一个特殊操作系统(xinu)的一部分。该函数是从c代码中调用的。我使用的一个引用是:http://www.unixwiz.net/techtips/win32-callconv-asm.html
这部分代码是在进程切换之前将其保存到堆栈中的部分。new_sp指向的堆栈也是以这种方式保存的。
.text
.globl callsw
/*---------------------------------------------------------------------
* callsw - call is callsw(&old_sp, &new_sp, &call_back)
*---------------------------------------------------------------------*/
callsw:
/*keep all of the old contex switch instructions so it will work with
with cxtsw*/
pushl %ebp /* push ebp onto stack */
movl %esp,%ebp /* record current SP in ebp */
pushfl /* record flags */
pushal /* save general regs on stack */
/* save old segment registers here, if multiple allowed */
movl 8(%ebp),%eax /* Get mem location in which to */
/* save the old process's SP */
movl %esp,(%eax) /* save old process's SP */
movl 12(%ebp),%eax /* Get location from which to */这里开始了切换到回调函数的代码。我希望回调函数运行,然后返回执行与new_sp堆栈关联的代码。
/* Switch to a new stach instead */
movl (%eax),%esp /* pick up new process's SP */
/* restore new seg. registers here, if multiple allowed */
popal /* restore general registers */
movl (%ebp),%eax /*keep old ebp for acess to arg 3*/
movl 4(%esp),%ebp /* pick up ebp before restoring */
/* interrupts */
popfl /* restore interrupt mask */
add $4,%esp /* skip saved value of ebp */
/* Switch to a new call back instead */
movl (%eax),%esp /* pick up new process's SP */
/* restore new seg. registers here, if multiple allowed */
popal /* restore general registers */
movl (%ebp),%eax /*keep old ebp for acess to arg 3*/
movl 4(%esp),%ebp /* pick up ebp before restoring */
/* interrupts */
popfl /* restore interrupt mask */
add $4,%esp /* skip saved value of ebp */这是我尝试设置堆栈并跳转到新进程的地方。我调用的函数是一个没有参数和返回值的c函数。
pop %ebx /* save the ra*/
movl %esp,%ebp /* move the base pointer to the bottom of the stack */
add -18,%ebp /* move stack down*/
/*set up stack and jump */
movl %ebp,%esp /* nothing on stack they are = */
movl %ebx, 0(%ebp) /* save ebp to stack */
movl %ebx, 4(%ebp) /* save ra */
movl 16(%eax),%ecx
JMP (%ecx) /* jump to call_back */发布于 2013-04-09 12:44:20
我想你的问题出在这里:
popal /* restore general registers */
movl (%ebp),%eax /*keep old ebp for acess to arg 3*/popal从保存在您要切换到的堆栈上的寄存器中恢复所有寄存器(包括ebp)。因此,movl (%ebp),%eax从新堆栈加载一个值(实际上是属于callsw的调用方的%ebp的值。所以当你以后这样做的时候
movl (%eax),%esp /* pick up new process's SP */您将不会获得新进程的SP --您将从堆栈的两个级别(callsw的调用者的调用者)获取帧指针。
https://stackoverflow.com/questions/15893094
复制相似问题