【问题标题】:C call back function from assembly (x86) and process switching从程序集 (x86) 和进程切换的 C 回调函数
【发布时间】:2013-03-31 08:39:47
【问题描述】:

此代码适用于我的本科操作系统课程。我试图在 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        */

【问题讨论】:

  • 如果我得到它工作我会在作业到期后发布我的解决方案

标签: c assembly callback operating-system x86


【解决方案1】:

我认为你的问题在这里:

popal                   /* restore general registers    */
movl    (%ebp),%eax     /*keep old ebp for acess to arg 3*/

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

movl    (%eax),%esp     /* pick up new process's SP     */

你没有得到新进程的 SP——你从堆栈的上两层(callsw 的调用者的调用者)获取帧指针。

【讨论】:

  • 感谢您的反馈。明天我去看看。
猜你喜欢
  • 2018-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-07
  • 1970-01-01
  • 1970-01-01
  • 2017-01-18
  • 2012-03-09
相关资源
最近更新 更多