搜索
bottom↓
回复: 2

分享:c51指针函数数组取长度-sizeof

[复制链接]

出0入0汤圆

发表于 2018-2-13 12:11:54 | 显示全部楼层 |阅读模式
想把代码写的更可配置一些,尝试指针函数,在用 sizeof 的时候遇到些问题贴出来给大家分享

* 示例函数
  1. void dosomething(void) {
  2.         static int i=0;
  3.         i=i+1;
  4. }
复制代码


* 示例指针函数数组
  1. void (*p_array[])(void) = {
  2.                                                                                                                 dosomething,
  3.                                                                                                                 dosomething,
  4.                                                                                                                 dosomething,
  5.                                                                                                                 dosomething,
  6.                                                                                                                 dosomething,
  7.                                                                                                                 dosomething,
  8.                                                                                                                 dosomething,
  9.                                                                                                                 dosomething,
  10.                                                                                                                 dosomething,
  11.                                                                                                                 dosomething,
  12.                                                                                                         };
复制代码



*出错的调用函数
  1. int main(void)
  2. {
  3.         for(array_size = 0;array_size < sizeof(p_array)/sizeof(int);array_size++)        {
  4.                 (*p_array[array_size])();
  5.         }
  6.         while(1);
  7. }
复制代码


*跑通的用法
  1. int main(void)
  2. {
  3.         for(array_size = 0;array_size < sizeof(p_array)/sizeof(p_array[0]);array_size++)        {
  4.                 (*p_array[array_size])();
  5.         }
  6.         while(1);
  7. }
复制代码


错误分析,我想当然的以为 void (*p_array[])(void) 每个元素的长度是两位。结果跑飞了
正确的在这里:
  1. stmt level  source
  2.    1        int *p1;           /* generic ptr (3 bytes) */
  3.    2        int xdata *p2;     /* xdata ptr (2 bytes) */
  4.    3        int idata *p3;     /* idata ptr (1 byte) */
  5.    4        int code *p4;      /* code ptr (2 bytes */
  6.    5
  7.    6        void pconvert (void) {
  8.    7   1    p1 = p2;           /* xdata* to generic* */
  9.    8   1    p1 = p3;           /* idata* to generic* */
  10.    9   1    p1 = p4;           /* code*  to generic* */
  11.   10   1
  12.   11   1    p4 = p1;           /* generic* to code* */
  13.   12   1    p3 = p1;           /* generic* to idata* */
  14.   13   1    p2 = p1;           /* generic* to xdata* */
  15.   14   1
  16.   15   1    p2 = p3;           /* idata* to xdata* (WARN) */
  17. *** WARNING 259 IN LINE 15 OF P.C: pointer: different mspace
  18.   16   1    p3 = p4;           /* code*  to idata* (WARN) */
  19. *** WARNING 259 IN LINE 16 OF P.C: pointer: different mspace
  20.   17   1    }

  21. ASSEMBLY LISTING OF GENERATED OBJECT CODE
  22.       ; FUNCTION pconvert (BEGIN)
  23.                       ; SOURCE LINE # 7
  24. 0000 750001 R   MOV  p1,#01H
  25. 0003 850000 R   MOV  p1+01H,p2
  26. 0006 850000 R   MOV  p1+02H,p2+01H
  27.                       ; SOURCE LINE # 8
  28. 0009 750000 R   MOV  p1,#00H
  29. 000C 750000 R   MOV  p1+01H,#00H
  30. 000F 850000 R   MOV  p1+02H,p3
  31.                       ; SOURCE LINE # 9
  32. 0012 7B05       MOV  R3,#0FFH
  33. 0014 AA00   R   MOV  R2,p4
  34. 0016 A900   R   MOV  R1,p4+01H
  35. 0018 8B00   R   MOV  p1,R3
  36. 001A 8A00   R   MOV  p1+01H,R2
  37. 001C 8900   R   MOV  p1+02H,R1
  38.                       ; SOURCE LINE # 11
  39. 001E AE02       MOV  R6,AR2
  40. 0020 AF01       MOV  R7,AR1
  41. 0022 8E00   R   MOV  p4,R6
  42. 0024 8F00   R   MOV  p4+01H,R7
  43.                       ; SOURCE LINE # 12
  44. 0026 AF01       MOV  R7,AR1
  45. 0028 8F00   R   MOV  p3,R7
  46.                       ; SOURCE LINE # 13
  47. 002A AE02       MOV  R6,AR2
  48. 002C 8E00   R   MOV  p2,R6
  49. 002E 8F00   R   MOV  p2+01H,R7
  50.                       ; SOURCE LINE # 15
  51. 0030 750000 R   MOV  p2,#00H
  52. 0033 8F00   R   MOV  p2+01H,R7
  53.                       ; SOURCE LINE # 16
  54. 0035 850000 R   MOV  p3,p4+01H
  55.                       ; SOURCE LINE # 17
  56. 0038 22         RET
  57.       ; FUNCTION pconvert (END)
复制代码


参考链接:http://www.keil.com/support/man/docs/c51/c51_le_ptrconversions.htm

另外还在软件仿真的时候,遇到 *** error 65: access violation at : no 'execute/read' permission
参考:http://blog.csdn.net/bobbat/article/details/41059721 的2条
2.仿真出现*** error 65: access violation at 0x0000000C : no 'read' permission的错误是因为没有相应的内存映射,可能的原因是由于软件仿真没有分配相应的映射地址。如果想要避开这个错误,可以再keil软件的仿真状态下面点击菜单栏的Debug-》Memory Map,如下图添加缺少的内存映射值范围,如0x0000000c在0x00000000-0x0000000f之间。如下图:

然后点击Map Range,最后close即可。在Run就没有错误了。

all;

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2018-2-13 12:24:43 | 显示全部楼层
51的RAM空间碎片化,在51上用指针一不小心就容易出错。

出0入0汤圆

发表于 2018-2-13 19:11:52 | 显示全部楼层
谢谢楼主 的好资料~~~~~~~~~~
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-27 21:19

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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