2013-04-09 240 views
2

此代碼適用於我的本科OS課程。我試圖在同一個new_sp堆棧上調用一個函數,然後返回任何new_sp正在做的事情。它不工作,我甚至不知道如何解決它。建議或解決方案會很好。如果有任何我遺漏的東西,請儘快通知我。彙編語言(x86)的C回調函數和進程切換

注:它是我們用於該類的特殊OS(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  */ 
+0

如果我得到它的工作我應該在分配完成後發佈我的解決方案 – JacksonReed 2013-04-09 18:06:37

回答

3

我覺得你的問題是在這裏:

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 - 你得到的幀指針從堆棧中的兩個級別(callw的調用者的調用者)

+0

感謝您的反饋,我明天再看看它。 – JacksonReed 2013-04-09 06:08:23

+0

popal是問題,謝謝 – JacksonReed 2013-04-09 17:40:35