2013-04-09 4 views
2

Этот код предназначен для моего курса ОС. Я пытаюсь вызвать функцию в том же стеке new_sp, а затем вернуться к тому, что делал new_sp. Он не работает, и я даже не уверен, как его удалить. Предложения или решение будут замечательными. Я пытался пробиться, если что-то у меня осталось, пожалуйста, дайте мне знать.C функция обратного вызова из сборки (x86) и переключение процессов

Примечания: Это часть специальной ОС (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

ответ

3

Я думаю, ваша проблема здесь:

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).

+0

Спасибо за обратную связь. Взгляните на него завтра. – JacksonReed

+0

Проблема с popal. – JacksonReed

 Смежные вопросы

  • Нет связанных вопросов^_^