setjmp和longjmp简介

setjmp和longjmp简介

1 setjmp和longjmp简介

  与刺激的abort函数和exit函数相比,goto语句看起来是处理异常的更可行方案。但是goto是本地的,它只能跳到所在函数内部的标号上,而不能将控制权转移到所在程序的任意地点(当然,除非你的所有代码都在main体中)。
为了解决这个限制,C函数库提供了setjmp函数和longjmp函数,它们分别承担非局部标号和goto作用。头文件

#include <setjmp.h>
#include <stdio.h>

jmp_buf j;

void raise_exception(void)
{
printf("exception raised\n");
longjmp(j, 3); /* jump to exception handler case 3 */
printf("this line should never appear\n");
}

int main(void)
{
switch (setjmp(j)) {
case 0:
printf("''setjmp'' is initializing ''j''\n");
raise_exception();
printf("this line should never appear\n");
case 1:
printf("Case 1\n");break;
case 2:
printf("Case 2\n");break;
case 3:
printf("Case 3\n");break;
default:
break;
}
return 0;
}

  最终的输出结果如下所示。

''setjmp'' is initializing ''j''
exception raised
Case 3

2 SylixOS下实现

  SylixOS未使用C库中的setjmp与longjmp函数,而是重新在各个架构中实现。如MIPS架构便是在/libsyllixos/SylixOS/arch/mips/common/mipsLibAsm.S文件中实现这两个函数,其代码如下所示。

;/**************************************************************************
;  sigsetjmp (参数为 jmp_buf, mask_saved)
;**************************************************************************/

FUNC_DEF(sigsetjmp)
    CALL_SETUP  __sigsetjmpSetup

    SAVE_NON_VOLATILE_REG

    JR          RA
    MOV         V0 , ZERO
    FUNC_END(sigsetjmp)
;/**************************************************************************
;  longjmp (参数为 jmp_buf, retval)
;**************************************************************************/

FUNC_DEF(longjmp)
CALL_SETUP  __longjmpSetup

RESTORE_NON_VOLATILE_REG

MOV         V0 , A1
BNE         V0 , ZERO , longjmpnotzero
NOP
LI          V0 , 1
LINE_LABEL(longjmpnotzero)
JR          RA
NOP
FUNC_END(longjmp)

3 参考资料

  《百度百科》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值