首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C程序集回调函数(x86)和进程切换

C程序集回调函数(x86)和进程切换
EN

Stack Overflow用户
提问于 2013-04-09 12:04:40
回答 1查看 1.5K关注 0票数 2

这段代码是为我的本科生OS课程编写的。我尝试在同一个new_sp堆栈上调用一个函数,然后返回到new_sp正在做的事情。它不工作,我甚至不确定如何调试它。建议或解决方案将是很好的。我试着读完了,如果有什么遗漏的,请告诉我。

注意:它是我们为这个类使用的一个特殊操作系统(xinu)的一部分。该函数是从c代码中调用的。我使用的一个引用是:http://www.unixwiz.net/techtips/win32-callconv-asm.html

这部分代码是在进程切换之前将其保存到堆栈中的部分。new_sp指向的堆栈也是以这种方式保存的。

代码语言:javascript
复制
    .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堆栈关联的代码。

代码语言:javascript
复制
    /* 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函数。

代码语言:javascript
复制
    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        */
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-04-09 12:44:20

我想你的问题出在这里:

代码语言:javascript
复制
popal                   /* restore general registers    */
movl    (%ebp),%eax     /*keep old ebp for acess to arg 3*/

popal从保存在您要切换到的堆栈上的寄存器中恢复所有寄存器(包括ebp)。因此,movl (%ebp),%eax从新堆栈加载一个值(实际上是属于callsw的调用方的%ebp的值。所以当你以后这样做的时候

代码语言:javascript
复制
movl    (%eax),%esp     /* pick up new process's SP     */

您将不会获得新进程的SP --您将从堆栈的两个级别(callsw的调用者的调用者)获取帧指针。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15893094

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档