2012-05-16 190 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

相關問題