2012-05-16 224 views
1

(这是我第一次在这里提出问题,英文不是我的第一语言,所以请原谅我的一些错误。 )如何使用内联汇编程序保存寄存器值

我在做我的操作系统作业时遇到了这个问题,我们被要求模拟函数SwitchToFiber,而我目前的问题是我不知道如何保存寄存器值以便下次恢复函数被称为。

我不知道我的问题是否清楚。虽然我不认为我的代码有用,但我会把它们放在下面。

#include <stdio.h> 

#define INVALID_THD NULL 
#define N 5 
#define REG_NUM 32 
unsigned store[N][REG_NUM]; 
typedef struct 
{ 
    void (*address) (void * arg); 
    void* argu; 
}thread_s; 

thread_s ts[N]; 

void StartThds(); 
void YieldThd(); 
void *CreateThd(void (*ThdFunc)(void*), void * arg); 
void thd1(void * arg); 
void thd2(void * arg); 
void StartThds() 
{ 

} 

void YieldThd() 
{ 
    thd2((void*)2); 

} 

void *CreateThd(void (*ThdFunc)(void*), void * arg) 
{ 
    ts[(int)arg].address = (*ThdFunc); 
    ts[(int)arg].argu = arg; 
} 

void thd2(void * arg) 
{ 
    for (int i = 4; i < 12; i++) 
    { 
     printf("\tthd2: arg=%d , i = %d\n", (int)arg, i); 
     //in order to see clearly,i added /t abouve 
     YieldThd(); 
    } 
} 

void thd1(void * arg) 
{ 
/* 
    __asm__(

    ); 
*/ 
    for (int i = 0; i < 12; i++) 
    { 
     printf("thd1: arg=%d , i = %d\n", (int)arg, i); 
     YieldThd(); 
    } 
} 

int main() 
{ 
    //this is my first plan, to store the register value in some static arry 
    for(int i = 0; i<N; i++) 
     for(int j = 0; j<REG_NUM; j++) 
      store[i][j] = 0; 
    //create the two thread 
    if (CreateThd(thd1, (void *)1) == INVALID_THD) 
    { 
     printf("cannot create\n"); 
    } 
    if (CreateThd(thd2, (void *)2) == INVALID_THD) 
    { 
     printf("cannot create\n"); 
    } 


    ts[1].address(ts[1].argu);  //thd1((void*)1),argu = 1; 
// StartThds(); 
    return 0; 
} 

这是我现在的整个代码,因为我不知道哪个部分可能有用,所以我把它们放在上面。正如你所看到的,他们中的大多数仍然是空的。

+0

我们在谈论什么CPU?你的汇编代码在哪里?顺便说一句,这看起来很像实现C的'setjmp()'/'longjmp()'(提示)。 –

+0

好吧,我的CPU似乎是Pentium4,而我正在使用C-FREE编译。我甚至不知道如何开始我的汇编代码,所以没有任何东西。 – shellbye

+0

那么学习一些程序集并返回具体问题怎么样? –

回答

1

这是可能的(如在评论中指出),您无需编写汇编这一点,或许你可以只使用setjmp()/longjmp()脱身,并让他们做必要的状态省电。

+0

我计划创建用户级线程,然后模拟计划,我的老师说只有'setjmp()/ longjmp()'是不够的,并且使用组合来保存寄存器是必要的。 – shellbye

+0

仅当他在2个线程之间切换时。如果是3,则必须存储/恢复自己。 – RedX

+0

是的,我想我可以模拟超过2,所以我认为是必要的,但我不知道如何... – shellbye

0

我已经做到了这一点,但我总是要查找细节。以下是当然只是伪代码。

基本上你要做的就是创建您注册一个结构:

typedef struct regs { 
    int ebx; //make sure these have the right size for the processors. 
    int ecx; 
    //... for all registers you wish to backup 
} registers; 

//when changing from one thread 
asm(//assembly varies from compiler to compiler check your manual 
    "mov ebx, thread1.register.ebx; 
    mov ecx, thread1.register.ecx;" 
    // and so on 

    //very important store the current program counter to the return address of this fu nction so we can continue from ther 
    // you must know where the return address is stored 
    "mov return address, thread1.register.ret" 
); 

//restore the other threads registers 
asm(
    "mov thread2.register.ebx, ebx; 
    mov thread2.register.ecx, ecx; 
    //now restoer the pc and let it run 
    mov thread2.register.ret, pc; //this will continue from where we stopped before 
); 

这是它如何工作的更多或更少的原则。既然你正在学习这一点,你应该能够自己找出其余的问题。

+0

非常感谢您的方向!我会尽我所能去做。 – shellbye

相关问题