LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
12
返回列表 发新帖
楼主: dieken_qfz

setjmp&longjmp的问题

[复制链接]
发表于 2005-7-8 18:48:07 | 显示全部楼层
Post by dieken_qfz
试过了, 我多拷贝了30个整型都不对。


不能移到case 1的后面,如果如此,后面的for循环会修改堆栈,就白restore了。


我是说把 restore 移到 f1 函数中的 case 1 后面.
回复 支持 反对

使用道具 举报

发表于 2005-7-8 18:50:58 | 显示全部楼层
改完后,类似于:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <setjmp.h>

  4. /*
  5. # define JB_BX        0
  6. # define JB_SI        1
  7. # define JB_DI        2
  8. # define JB_BP        3
  9. # define JB_SP        4
  10. # define JB_PC        5
  11. */

  12. #define JMPBUF(buf, idx) (((int*)buf)[idx])
  13. #define BX(buf) JMPBUF(buf, 0)
  14. #define SI(buf) JMPBUF(buf, 1)
  15. #define DI(buf) JMPBUF(buf, 2)
  16. #define BP(buf) JMPBUF(buf, 3)
  17. #define SP(buf) JMPBUF(buf, 4)
  18. #define PC(buf) JMPBUF(buf, 5)

  19. #define savestack() if (NULL != sp1 && NULL != sp2) { \
  20.         for (i=0; i < sp1 - sp2+20; ++i) { \
  21.                 stack[i] = *(sp2 + i);  \
  22.         } \
  23.         } else abort();

  24. #define restorestack() if (NULL != sp1 && NULL != sp2) { \
  25.         for (i=0; i < sp1 - sp2+20; ++i) { \
  26.                 *(sp2 + i) = stack[i];  \
  27.         } \
  28.         } else abort();

  29. jmp_buf buf1;
  30. jmp_buf buf2;
  31. int j1 = 1;
  32. int j2 = 1;
  33. int i = 0;
  34. int* sp1 = NULL;
  35. int* sp2 = NULL;
  36. int stack[1024];

  37. void output(jmp_buf buf) {
  38.         int* p = (int*)buf;
  39.         int  i = 0;
  40.         printf("BX=%u, SI=%u, DI=%u, BP=%u, SP=%u, PC=%u\n",
  41.                         p[0], p[1], p[2], p[3], p[4], p[5]);
  42.         printf("stack from SP: ");
  43.         for (i = 0; i < 30; ++i) {
  44.                 printf("%u ", *(int*)(p[4] + i));
  45.         }
  46.         printf("\n&output()=%u, p =%u, buf=%u\n", output, p, (int*)buf);
  47. }

  48. void f1() {
  49.         int a = 6;
  50.         int b = 7;
  51.         int c = 8;
  52.         printf("f1: enter: \t\ta=%x, b=%x, c=%x\n", a, b, c);
  53.         switch (setjmp(buf2)) {
  54.                 case 0:
  55.                         sp2 = (int*)SP(buf2);
  56.                         printf("f1: case 0: \t\ta=%x, b=%x, c=%x\n", a, b, c);
  57.                         savestack();
  58.                         if (j1) longjmp(buf1, 1);
  59.                         printf("f1: case 0: after longjump\n");
  60.                         break;
  61.                 case 1:
  62.                 restorestack();
  63.                         printf("f1: case 1: jump from main\n");
  64.                         printf("f1: \t\ta=%x, b=%x, c=%x\n", a, b, c);
  65.                         printf("&buf1=%x, &buf2=%x, &a=%x, &b=%x, c=%x\n", &buf1, &buf2,
  66.                                         &a, &b, &c);
  67.                         break;
  68.         }
  69.         printf("f1: leave: \t\ta=%x, b=%x, c=%x\n", a, b, c);
  70. }
  71. int main(int argc, char** argv) {
  72.         int x = 3;
  73.         int y = 4;
  74.         int z = 5;
  75.         (void)argc;
  76.         (void)argv;
  77.         printf("main: enter: \t\tx=%x, y=%x, z=%x\n", x, y, z);
  78.         switch (setjmp(buf1)) {
  79.                 case 0:
  80.                         sp1 = (int*)SP(buf1);
  81.                         printf("main: case 0: call f1(): \t\tx=%x, y=%x, z=%x\n", x, y, z);
  82.                         f1();
  83.                         printf("main: case 0: back from f1()\n");
  84.                         break;
  85.                 case 1:
  86.                         printf("main: case 1\n");
  87.                         {
  88.                                 int aa[512];
  89.                                 int i;
  90.                                 for (i=0; i < 512; ++i) {
  91.                                         aa[i] = 512 - i;
  92.                                 }
  93.                         }
  94.                         printf("main: case 1: jump to f1(): \t\tx=%x, y=%x, z=%x\n", x, y, z);
  95.                        
  96.                         if (j2) longjmp(buf2, 1);
  97.                         printf("main: case 1: back from f1()\n");
  98.                         break;
  99.         }
  100.         printf("main: leave: \t\tx=%x, y=%x, z=%x\n", x, y, z);
  101.         return 0;
  102. }
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-7-11 08:38:54 | 显示全部楼层
嗯, 的确是这样, 呵呵, 多谢rickxbx兄!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表