《程序员的自我修养》书中的一个例子的问题

发布于 2022-10-15 08:44:00 字数 11421 浏览 25 评论 0

书中第7章,有个叫runso的例子,我跑了下,有些问题,本来想给作者发个mail,但是书上还真没找到,大家有空帮小弟看看

代码是这样的:

  1. #include <stdio.h>
  2. #include <dlfcn.h>
  3. #define SETUP_STACK                              \
  4.         i = 2;                                       \
  5.         while (++i < argc - 1) {                     \
  6.                 printf("i: %d\n", i);\
  7.                 switch (argv[i][0]) {                    \
  8.                         case 'i':                            \
  9.                                 printf("%d\n", i);\
  10.                                 asm volatile("push %0" ::        \
  11.                                 "r"(atoi(&argv[i][1])) );             \
  12.                             esp += 4;                        \
  13.                                 printf("%d\n", i);\
  14.                                 break;                           \
  15.                         case 'd':                            \
  16.                                 atof(&argv[i][1]);               \
  17.                                 asm volatile("subl $8, %esp\n"   \
  18.                                 "fstpl (%esp)" );                \
  19.                                 esp += 8;                        \
  20.                             break;                           \
  21.                         case 's':                            \
  22.                                 asm volatile("push %0" ::        \
  23.                                 "r"(&argv[i][1]) );               \
  24.                             esp += 4;                        \
  25.                             break;                           \
  26.                         default:                             \
  27.                             printf("error argument type");   \
  28.                             goto exit_runso;                 \
  29.                 }                                        \
  30.                 printf("%d\n", i);\
  31.         }
  32. #define RESOTRE_STACK                      \
  33.         asm volatile("add %0, %%esp"::"r"(esp))
  34. int main(int argc, char* argv[])
  35. {
  36.         void *handle;
  37.         char *error;
  38.         int i;
  39.         int esp = 0;
  40.         void *func;
  41.         handle = dlopen(argv[1], RTLD_NOW);
  42.         if(0 == handle)
  43.         {
  44.                 printf("Can't find library: %s\n", argv[1]);
  45.                 return -1;
  46.         }
  47.         func = dlsym(handle, argv[2]);
  48.         if ((error = dlerror()) != NULL)
  49.         {
  50.                 printf("Find symbol %s error: %s\n", argv[2], error);
  51.                 goto exit_runso;
  52.         }
  53.         switch (argv[argc - 1][0])
  54.         {
  55.                 case 'i':
  56.                 {
  57.                         int (*func_int)() = func;
  58.                         SETUP_STACK;
  59.                         printf("%p\n", func_int);
  60.                         int ret = func_int();
  61.                         RESOTRE_STACK;
  62.                         printf("ret = %d\n", ret);
  63.                         break;
  64.                 }
  65.                 case 'd':
  66.                 {
  67.                         double (*func_double)() = func;
  68.                         SETUP_STACK;
  69.                         double ret = func_double();
  70.                         RESOTRE_STACK;
  71.                         printf("ret = %f\n", ret);
  72.                         break;
  73.                 }
  74.                 case 's':
  75.                 {
  76.                         char* (*func_str)() = func;
  77.                         SETUP_STACK;
  78.                         char *ret = func_str();
  79.                         RESOTRE_STACK;
  80.                         printf("ret = %s\n", ret);
  81.                         break;
  82.                 }
  83.                 case 'v':
  84.                 {
  85.                         void (*func_void)() = func;
  86.                         SETUP_STACK;
  87.                         func_void();
  88.                         RESOTRE_STACK;
  89.                         printf("ret = void");
  90.                         break;
  91.                 }
  92.         }/* end of switch */
  93. exit_runso:
  94.         dlclose(handle);
  95. }

复制代码运行:./runso /lib/libm-2.6.1.so sin d2.0 d

但是运行时出现segment fault,  代码和书上的一样,我跟了下发现在SETUP_STACK 宏里面出现的错误,这里本来是要把命令行里的参数解析后压入栈中,后面程序调用时使用,
但是我发现 在入栈的那段汇编代码运行后,栈就坏了,那个变量i就变成0了,所有我感觉这样的操作栈是不是不太合理,有什么解决方法吗? 或者有谁能联系到作者?问问他。。。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文