免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1671 | 回复: 3
打印 上一主题 下一主题

关于APUE书中讲的setjmp和longjmp [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-11-19 09:14 |只看该作者 |倒序浏览
示例程序来自apue2的7.13,程序如下
#include "apue.h"
#include <setjmp.h>

static void f1(int, int, int, int);
static void f2(void);

static jmp_buf jmpbuffer;
static int     globval;

int
main(void)
{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int             autoval;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;register int    regival;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;volatile int    volaval;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;static int      statval;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;globval = 1; autoval = 2; regival = 3; volaval = 4; statval = 5;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (setjmp(jmpbuffer) != 0) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("after longjmp:\n");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("globval = %d, autoval = %d, regival = %d,"
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" volaval = %d, statval = %d\n",
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;globval, autoval, regival, volaval, statval);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(0);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* Change variables after setjmp, but before longjmp.
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;globval = 95; autoval = 96; regival = 97; volaval = 98;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;statval = 99;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f1(autoval, regival, volaval, statval); /* never returns */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(0);
}

static void
f1(int i, int j, int k, int l)
{
&nbsp;&nbsp;&nbsp;&nbsp;printf("in f1():\n");
&nbsp;&nbsp;&nbsp;&nbsp;printf("globval = %d, autoval = %d, regival = %d,"
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" volaval = %d, statval = %d\n", globval, i, j, k, l);
&nbsp;&nbsp;&nbsp;&nbsp;f2();
}
static void
f2(void)
{
&nbsp;&nbsp;&nbsp;&nbsp;longjmp(jmpbuffer, 1);
}


用gcc 编译后,运行结果是:

  $ ./a.out
    in f1():
    globval = 95, autoval = 96, regival = 97, volaval = 98, statval = 99
    after longjmp:
    globval = 95, autoval = 96, regival = 97, volaval = 98, statval = 99

论坛徽章:
0
2 [报告]
发表于 2008-11-19 09:16 |只看该作者
用gcc -S 生成汇编程序如下:
&nbsp;&nbsp;&nbsp;&nbsp;.file&nbsp;&nbsp;&nbsp;&nbsp;"testjmp.c"
&nbsp;&nbsp;&nbsp;&nbsp;.local&nbsp;&nbsp;&nbsp;&nbsp;statval.3342
&nbsp;&nbsp;&nbsp;&nbsp;.comm&nbsp;&nbsp;&nbsp;&nbsp;statval.3342,4,4
&nbsp;&nbsp;&nbsp;&nbsp;.section&nbsp;&nbsp;&nbsp;&nbsp;.rodata
.LC0:
&nbsp;&nbsp;&nbsp;&nbsp;.string&nbsp;&nbsp;&nbsp;&nbsp;"after longjmp:"
&nbsp;&nbsp;&nbsp;&nbsp;.align 4
.LC1:
&nbsp;&nbsp;&nbsp;&nbsp;.string&nbsp;&nbsp;&nbsp;&nbsp;"globval = %d, autoval = %d, regival = %d, volaval = %d, statval = %d\n"
&nbsp;&nbsp;&nbsp;&nbsp;.text
.globl main
&nbsp;&nbsp;&nbsp;&nbsp;.type&nbsp;&nbsp;&nbsp;&nbsp;main, @function
main:
&nbsp;&nbsp;&nbsp;&nbsp;leal&nbsp;&nbsp;&nbsp;&nbsp;4(%esp), %ecx
&nbsp;&nbsp;&nbsp;&nbsp;andl&nbsp;&nbsp;&nbsp;&nbsp;$-16, %esp
&nbsp;&nbsp;&nbsp;&nbsp;pushl&nbsp;&nbsp;&nbsp;&nbsp;-4(%ecx)
&nbsp;&nbsp;&nbsp;&nbsp;pushl&nbsp;&nbsp;&nbsp;&nbsp;%ebp
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;%esp, %ebp
&nbsp;&nbsp;&nbsp;&nbsp;pushl&nbsp;&nbsp;&nbsp;&nbsp;%ecx
&nbsp;&nbsp;&nbsp;&nbsp;subl&nbsp;&nbsp;&nbsp;&nbsp;$52, %esp
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;$1, globval
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;$2, -8(%ebp)
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;$3, -24(%ebp)
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;$4, -12(%ebp)
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;$5, statval.3342
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;$jmpbuffer, (%esp)
&nbsp;&nbsp;&nbsp;&nbsp;call&nbsp;&nbsp;&nbsp;&nbsp;_setjmp
&nbsp;&nbsp;&nbsp;&nbsp;testl&nbsp;&nbsp;&nbsp;&nbsp;%eax, %eax
&nbsp;&nbsp;&nbsp;&nbsp;je&nbsp;&nbsp;&nbsp;&nbsp;.L2
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;$.LC0, (%esp)
&nbsp;&nbsp;&nbsp;&nbsp;call&nbsp;&nbsp;&nbsp;&nbsp;puts
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;statval.3342, %eax
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;-12(%ebp), %edx
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;globval, %ecx
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;%eax, 20(%esp)
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;%edx, 16(%esp)
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;-24(%ebp), %eax
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;%eax, 12(%esp)
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;-8(%ebp), %eax
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;%eax, 8(%esp)
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;%ecx, 4(%esp)
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;$.LC1, (%esp)
&nbsp;&nbsp;&nbsp;&nbsp;call&nbsp;&nbsp;&nbsp;&nbsp;printf
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;$0, (%esp)
&nbsp;&nbsp;&nbsp;&nbsp;call&nbsp;&nbsp;&nbsp;&nbsp;exit
.L2:
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;$95, globval
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;$96, -8(%ebp)
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;$97, -24(%ebp)
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;$98, -12(%ebp)
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;$99, statval.3342
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;statval.3342, %eax
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;-12(%ebp), %edx
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;%eax, 12(%esp)
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;%edx, 8(%esp)
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;-24(%ebp), %eax
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;%eax, 4(%esp)
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;-8(%ebp), %eax
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;%eax, (%esp)
&nbsp;&nbsp;&nbsp;&nbsp;call&nbsp;&nbsp;&nbsp;&nbsp;f1
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;$0, (%esp)
&nbsp;&nbsp;&nbsp;&nbsp;call&nbsp;&nbsp;&nbsp;&nbsp;exit
&nbsp;&nbsp;&nbsp;&nbsp;.size&nbsp;&nbsp;&nbsp;&nbsp;main, .-main
&nbsp;&nbsp;&nbsp;&nbsp;.section&nbsp;&nbsp;&nbsp;&nbsp;.rodata
.LC2:
&nbsp;&nbsp;&nbsp;&nbsp;.string&nbsp;&nbsp;&nbsp;&nbsp;"in f1():"
&nbsp;&nbsp;&nbsp;&nbsp;.text
&nbsp;&nbsp;&nbsp;&nbsp;.type&nbsp;&nbsp;&nbsp;&nbsp;f1, @function
f1:
&nbsp;&nbsp;&nbsp;&nbsp;pushl&nbsp;&nbsp;&nbsp;&nbsp;%ebp
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;%esp, %ebp
&nbsp;&nbsp;&nbsp;&nbsp;subl&nbsp;&nbsp;&nbsp;&nbsp;$24, %esp
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;$.LC2, (%esp)
&nbsp;&nbsp;&nbsp;&nbsp;call&nbsp;&nbsp;&nbsp;&nbsp;puts
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;globval, %edx
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;20(%ebp), %eax
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;%eax, 20(%esp)
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;16(%ebp), %eax
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;%eax, 16(%esp)
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;12(%ebp), %eax
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;%eax, 12(%esp)
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;8(%ebp), %eax
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;%eax, 8(%esp)
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;%edx, 4(%esp)
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;$.LC1, (%esp)
&nbsp;&nbsp;&nbsp;&nbsp;call&nbsp;&nbsp;&nbsp;&nbsp;printf
&nbsp;&nbsp;&nbsp;&nbsp;call&nbsp;&nbsp;&nbsp;&nbsp;f2
&nbsp;&nbsp;&nbsp;&nbsp;leave
&nbsp;&nbsp;&nbsp;&nbsp;ret
&nbsp;&nbsp;&nbsp;&nbsp;.size&nbsp;&nbsp;&nbsp;&nbsp;f1, .-f1
&nbsp;&nbsp;&nbsp;&nbsp;.type&nbsp;&nbsp;&nbsp;&nbsp;f2, @function
f2:
&nbsp;&nbsp;&nbsp;&nbsp;pushl&nbsp;&nbsp;&nbsp;&nbsp;%ebp
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;%esp, %ebp
&nbsp;&nbsp;&nbsp;&nbsp;subl&nbsp;&nbsp;&nbsp;&nbsp;$8, %esp
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;$1, 4(%esp)
&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;$jmpbuffer, (%esp)
&nbsp;&nbsp;&nbsp;&nbsp;call&nbsp;&nbsp;&nbsp;&nbsp;longjmp
&nbsp;&nbsp;&nbsp;&nbsp;.size&nbsp;&nbsp;&nbsp;&nbsp;f2, .-f2
&nbsp;&nbsp;&nbsp;&nbsp;.local&nbsp;&nbsp;&nbsp;&nbsp;jmpbuffer
&nbsp;&nbsp;&nbsp;&nbsp;.comm&nbsp;&nbsp;&nbsp;&nbsp;jmpbuffer,156,32
&nbsp;&nbsp;&nbsp;&nbsp;.local&nbsp;&nbsp;&nbsp;&nbsp;globval
&nbsp;&nbsp;&nbsp;&nbsp;.comm&nbsp;&nbsp;&nbsp;&nbsp;globval,4,4
&nbsp;&nbsp;&nbsp;&nbsp;.ident&nbsp;&nbsp;&nbsp;&nbsp;"GCC: (GNU) 4.1.2 20070626 (Red Hat 4.1.2-14)"
&nbsp;&nbsp;&nbsp;&nbsp;.section&nbsp;&nbsp;&nbsp;&nbsp;.note.GNU-stack,"",@progbits


从这个程序里可以看到,globval 和statval并非是分配在栈上,
照理说longjmp后输出的应该是改变后的值啊?
高手帮忙看下,
谢谢了~~

论坛徽章:
0
3 [报告]
发表于 2008-11-19 09:19 |只看该作者

回复 #1 BLZer 的帖子

你想说什么。。
不优化是这样啊

论坛徽章:
0
4 [报告]
发表于 2008-11-19 09:23 |只看该作者
既然globval和statval没分配在栈上,那么当longjmp回来后,

这两个变量应该不会变成压栈前的值吧?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP