如何使用内联汇编程序保存寄存器值

时间:2012-05-16 08:43:02

标签: c++ c assembly x86

(嗯,这是我第一次在这里提问,英语不是我的第一语言,所以请原谅我的一些错误。而且我是一个绿色的程序。)

我在做OS作业时遇到了这个问题,我们被要求模拟函数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;
}

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

2 个答案:

答案 0 :(得分:1)

有可能(正如评论中所指出的那样)你不需要为此编写程序集,也许只需使用setjmp()/longjmp()即可完成,并让它们进行必要的状态保存。

答案 1 :(得分: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
);

这或多或少是它的工作原理。既然你正在学习这个,你应该能够自己弄清楚其余部分。