11-08-05 11:29 PM
> The 'mylongjmp' can't be reasonably implemented with inline assembly.
> You'll have to use "pure" assembly if you are to have any chance
> of success. Also note that setjmp/longjmp must save *all* registers.
> At a minimum you must save/resore %esp in addition to %ebp.
I never wrote the whole program by pure assembly before, and it seems
easier with inline assembly.
By the way, I must save all registers? I read the code of setjmp in
glibc, and did not find setjmp save all registers. But I did not find
longjmp in glibc, so I tried to write them by myself.
I have modified my program, and it seems to run well.But I am not sure
that it can really work well in all conditions.
typedef struct __myjmp_buf
{
int efp;
int epc;
int esp;
}myjmp_buf[1];
int mysetjmp(myjmp_buf env)
{
__asm__("movl (%%ebp),%0":"=r"(env[0].efp));
__asm__("movl %%esp,%0":"=r"(env[0].esp));
__asm__("movl 4(%%ebp),%0":"=r"(env[0].epc));
return 0;
}
void mylongjmp(myjmp_buf env , int val)
{
__asm__(
"movl %0,%%ebp\n\t"
"movl %3,%%esp\n\t"
"leave\n\t"
"movl %1,%%eax\n\t"
"jmp %2"
::"r"(env[0].efp),
"r"(val),
"r"(env[0].epc),
"r"(env[0].esp));
}
myjmp_buf buf;
int test()
{
int i=0;
i++;
mylongjmp(buf , 1);
return 0;
}
int test1()
{
int reval;
if(reval=mysetjmp(buf)){
printf("return success,return value is %d\n" , reval);
}
else
test();
}
int main()
{
test1();
exit(0);
}
[ Post a follow-up to this message ]
|