setjmp()/longjmp()的使用方法

setjmp和longjmp.为了让你实现复杂的流控制,程序在系统里面运行完全依靠内存(代码段,全局段,堆存储器,栈存储器)和寄存器的内容(栈指针,基地址,计数器),setjmp保存当前的寄存器里面的内容,longjmp是恢复这些内容.longjmp返回setjmp程序当前的状态

先看一个例子:

#include <csetjmp>
#include <cstdio>
#include <windows.h>
int main()
{
  jmp_buf env;
  int i;

  i = setjmp(env);
  printf("i = %d\n", i);

  if (i != 0) exit(0);

  longjmp(env, 2);
  printf("Does this line get printed?\n");
  return 0;
}

可以知道函数int setjmp(jmp_buf env)和longjmp(jmp_buf env, int val)定义在头文件<csetjmp>中。

int setjmp(jmp_buf env);保存当前寄存器的状态到env这个结构体实例的数组里面,下面是jmp_buf结构体的定义:

typedef struct _jmp_buf
{
    int _jp[_JBLEN+1];
} jmp_buf[1];

  将 jmp_buf定义为一个数组,那么可以将数据分配在栈上,但是作为参数传递的时候传的是一个指针。

直接调用setjmp函数时,默认返回值是0;

longjmp(jmp_buf env, int val);longjmp将数组里面存储的内容恢复到寄存器里面.但是longjmp没有返回值.与之相反的是,当调用它的时候,只要你在调用setjmp保存了env,就OK了.因为其他寄存器被存储,PC才被保存.setjmp返回的值可以作为longjmp的参数val,但是不能为零.因此,如果setjmp返回非零值,并且返回值作为longjmp的参数,这样longjmp恢复的就是这个setjmp的环境.恢复环境之后继续执行setjmp(env)的下一条语句。

总之,setjmp和longjmp的作用相当于goto

时间: 2024-10-05 23:53:31

setjmp()/longjmp()的使用方法的相关文章

setjmp &amp; longjmp实现分析

如何使用setjmp & longjmp,就不再细说了,请参考APUE 7.10. 本文解释如下知识点:1.简单介绍X86_64的寄存器2.setjmp & longjmp是怎么实现的.3.为什么能从setjmp处多次返回.4.从setjmp返回时,那些数据是无效了,如何避免. 本文没有画出函数调用栈桢的图,如果对汇编不是很熟悉的话,最好边看边画^_^,会事关功倍. 下文是通过反汇编如下代码来分析的 #include <setjmp.h> #include <stdio.

函数 setjmp, longjmp, sigsetjmp, siglongjmp

一,相关函数接口 1,setjmp,longjmp,sigsetjmp,siglongjmp   #include <setjmp.h> int setjmp(jmp_buf env); int sigsetjmp(sigjmp_buf env, int savesigs);    //savesigs非0时,在env中保存进程当前信号屏蔽字. void longjmp(jmp_buf env, int val); void siglongjmp(sigjmp_buf env, int val

setjmp/longjmp

1.setjmp/longjmp属于传统的错误处理 2.setjmp/longjmp是对goto语句的补充,goto只能实现局部跳转,setjmp/longjmp可以实现全局跳转 3.setjmp/longjmp与goto都有缺陷 传统错误处理的3种方式是: 1.设置全局错误状态,标准c中使用errno与perror函数来支持 2.使用标准c库中的信号 3.使用setjmp/longjmp setjmp/longjmp

Linux setjmp longjmp

/********************************************************************* * Linux setjmp longjmp * 说明: * 最近在看cmockery源代码的时候发现setjmp和longjmp函数,于是查了 * 相关的内容,发现真是个好东西,可以完成函数之间的直接跳转. * * 2016-5-7 深圳 南山平山村 曾剑锋 ************************************************

c setjmp longjmp

http://coolshell.cn/?s=setjmp http://www.cnblogs.com/hazir/p/c_setjmp_longjmp.html 1 double divide(double to, double by, jmp_buf env) 2 { 3 if(by == 0) 4 if (env) 5 longjmp(env, 1); 6 else 7 return 0; 8 else 9 return to/by; 10 } 11 12 void f() 13 { 1

setjmp和longjmp

此文是学习 C专家编程 中的笔记. setjmp和longjmp是C语言所独有的,它们部分弥补了C语言有限的转移能力. 函数说明(来自wiki百科): int setjmp(jmp_buf env) 建立本地的jmp_buf缓冲区并且初始化,用于将来跳转回此处.这个子程序保存程序的调用环境于env参数所指的缓冲区,env将被longjmp使用.如果是从setjmp直接调用返回,setjmp返回值为0.如果是从longjmp恢复的程序调用环境返回,setjmp返回非零值. void longjmp

C语言中利用setjmp和longjmp做异常处理

错误处理是任何语言都需要解决的问题,只有不能保证100%的正确运行,就需要有处理错误的机制.异常处理就是其中的一种错误处理方式. 1 过程活动记录(Active Record) C语言中每当有一个函数调用时,就会在堆栈(Stack)上准备一个被称为AR的结构,抛开具体编译器实现细节的不同,这个AR基本结构如下所示. 每当遇到一次函数调用的语句,C编译器都会产生出汇编代码来在堆栈上分配这个AR.例如下面的C代码: void a(int i) { if(i==0){ i = 1; } else {

C语言中setjmp与longjmp学习笔记

一.基础介绍 ?? ?头文件:#include<setjmp.h> ?? ?原型:??int?setjmp(jmp_buf envbuf) ?? ?宏函数setjmp()在缓冲区envbuf中保存系统堆栈里的内容,供longjmp()以后使用.首次调用setjmp()宏时,返回值为0,然而longjmp()把一个变原传递给setjmp(),该值(恒不为0)就是调用longjmp()后出现的setjmp()的值. void longjmp(jmp_buf envbuf,int status);

【C语言天天练(五)】setjmp和longjmp

setjmp和longjmp组合可以实现跳转,与goto语句有相似的地方.但有以下不同: 1.用longjmp只能跳回到曾经到过的地方.在执行setjmp的地方仍留有一个过程活动记录.从这个角度看,longjmp更像是"从何处来"而不是"往何处去".longjmp接收一个额外的整型参数并返回它的值,这可以知道是由longjmp转移到这里的还是从上一条语句执行后自然而然来到这里的. 2.goto语句不能跳出C语言当前的函数,而longjmp可以跳的更远,可以跳出函数,