Chinaunix首页 | 论坛 | 博客
  • 博客访问: 167079
  • 博文数量: 18
  • 博客积分: 285
  • 博客等级: 二等列兵
  • 技术积分: 201
  • 用 户 组: 普通用户
  • 注册时间: 2012-07-02 11:26
文章分类

全部博文(18)

文章存档

2015年(2)

2014年(4)

2012年(12)

我的朋友

分类: LINUX

2012-11-07 00:03:50

今天偶然看到一段代码,是关于函数指针强制转化的,看了半天都没看明白。回来写了个形式类似的代码:

点击(此处)折叠或打开

  1. int add(int a, int b)
  2. {
  3.     return (a+b);
  4. }

  5. int sub(int a, int b,int c)
  6. {
  7.     c= c + 1;
  8.     return (a-b);
  9. }

  10. typedef int (*padd)(int, int);
  11. typedef int (*psub)(int, int, int);

  12. int main(void)
  13. {
  14.     int ret;
  15.     padd fun = (padd)sub;

  16.     ret = fun(2,3);
  17.     return 0;
  18. }
开始给 ret = fun(2,3,4),结果编译不通过,说参数个数太多,改为2个,通过。由此推测,强制类型转换后,函数参数的传递要按强制类型转换的函数指针类型声明来传递。也就是这里的 padd类型,需要2个int参数。不理解,于是汇编:

点击(此处)折叠或打开

  1. .file "a.c"
  2. .text
  3. .align 2
  4. .global add
  5. .type add, %function
  6. add:
  7. @ Function supports interworking.
  8. @ args = 0, pretend = 0, frame = 8
  9. @ frame_needed = 1, uses_anonymous_args = 0
  10. mov ip, sp
  11. stmfd sp!, {fp, ip, lr, pc}
  12. sub fp, ip, #4
  13. sub sp, sp, #8
  14. str r0, [fp, #-16]
  15. str r1, [fp, #-20]
  16. ldr r2, [fp, #-16]
  17. ldr r3, [fp, #-20]
  18. add r3, r2, r3
  19. mov r0, r3
  20. sub sp, fp, #12
  21. ldmfd sp, {fp, sp, lr}
  22. bx lr
  23. .size add, .-add
  24. .align 2
  25. .global sub
  26. .type sub, %function
  27. sub:
  28. @ Function supports interworking.
  29. @ args = 0, pretend = 0, frame = 16
  30. @ frame_needed = 1, uses_anonymous_args = 0
  31. mov ip, sp
  32. stmfd sp!, {fp, ip, lr, pc}
  33. sub fp, ip, #4
  34. sub sp, sp, #16
  35. str r0, [fp, #-16]
  36. str r1, [fp, #-20]
  37. str r2, [fp, #-24]
  38. ldr r3, [fp, #-24]
  39. add r3, r3, #1
  40. str r3, [fp, #-24]
  41. ldr r2, [fp, #-16]
  42. ldr r3, [fp, #-20]
  43. rsb r3, r3, r2
  44. mov r0, r3
  45. sub sp, fp, #12
  46. ldmfd sp, {fp, sp, lr}
  47. bx lr
  48. .size sub, .-sub
  49. .align 2
  50. .global main
  51. .type main, %function
  52. main:
  53. @ Function supports interworking.
  54. @ args = 0, pretend = 0, frame = 8
  55. @ frame_needed = 1, uses_anonymous_args = 0
  56. mov ip, sp
  57. stmfd sp!, {fp, ip, lr, pc}
  58. sub fp, ip, #4
  59. sub sp, sp, #8
  60. ldr r3, .L7
  61. str r3, [fp, #-16]
  62. ldr r3, [fp, #-16]
  63. mov r0, #2
  64. mov r1, #3
  65. mov lr, pc
  66. bx r3
  67. mov r3, r0
  68. str r3, [fp, #-20]
  69. mov r3, #0
  70. mov r0, r3
  71. sub sp, fp, #12
  72. ldmfd sp, {fp, sp, lr}
  73. bx lr
  74. .L8:
  75. .align 2
  76. .L7:
  77. .word sub
  78. .size main, .-main
  79. .ident "GCC: (GNU) 4.1.2"
果真如此,他最终调用的是sub,而不是add,那么sub需要的第三个参数怎么来,(arm函数参数传递<=4时用r0-r3来传,超出用堆栈),看到sub里面,r2被用上了,这时它是个随机的值。
函数体依旧用原来的,只是参数传递按强制类型的。看不出这样使用有什么作用?明天继续。

算是比较丢脸,自己连函数调用和函数指针转换都搞错了。此处本是一个函数调用而已,我去偏偏看成是个函数指针转换,浪费时间。貌似函数指针转换基本没意义。

阅读(3978) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~