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

2020-01-14 18:55发布

想把代码写的更可配置一些,尝试指针函数,在用 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之间。如下图:
20141113003449517.png (23.69 KB, 下载次数: 0) 下载附件 2018-2-13 12:10 上传
然后点击Map Range,最后close即可。在Run就没有错误了。

all;
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
2条回答
su33691
1楼-- · 2020-01-14 19:48
51的RAM空间碎片化,在51上用指针一不小心就容易出错。
lxa0
2楼-- · 2020-01-14 20:46
谢谢楼主 的好资料~~~~~~~~~~

一周热门 更多>