, ( , , ).
arg3caller . , . args3, , , . , , . args3, .
, arg3caller longjmp, , , , , . args3 ( , longjmp), , .
setjmp , , . setjmp globals ( setjmp jmpbuf, setjmp longjmp , ), . longjmp , . , longjmp, . ( ), , setjmp ( ).
, , , @duskwuff. -S, , asm gcc, , ( ).
Edit:
MIPS gcc, this MIPS gcc 5.4. , , - lr fp , ( a0, gcc , ). setjmp , , setjmp -, lr . arg lr fp, ( ) 0. , longjmp, , lr , fp sp. longjmp, fp , lr fp. longjmp, fp sp lr fp , , setjmp. 1, setjmp , longjmp.
, ! , (-O0). - , setjmp longjmp . , , , . , undefined, gcc . ( gdb spim), , , .
struct jmpbuf {
int lr;
int fp;
int *sp;
};
static struct jmpbuf ctx;
static void setjmp_leaf(void) { }
int setjmp(int arg)
{
setjmp_leaf();
ctx.sp = &arg;
ctx.lr = (&arg)[-1];
ctx.fp = (&arg)[-2];
return 0;
}
static void longjmp_leaf(int arg)
{
(&arg)[-1] = (int)ctx.sp;
}
int longjmp(int arg)
{
longjmp_leaf(arg);
(&arg)[-1] = ctx.lr;
(&arg)[-2] = ctx.fp;
return 1;
}
!