找回密码
 立即注册
楼主: rayrakey

51单片机函数指针问题

[复制链接]
  • 打卡等级:以坛为家II
  • 打卡总天数:435
  • 最近打卡:2025-04-30 08:43:23

33

主题

2351

回帖

4860

积分

论坛元老

积分
4860
发表于 2024-6-25 20:18:01 | 显示全部楼层
rayr*** 发表于 2024-6-25 18:04
就是这样,我晕我现在更懵了,尴尬了。

你可以思考一下 看看哪里用的不对了,,,

1.动态内存申请,,你这里是正确的,,但是后面用的时候要注意内存碎片问题。虽然之前用的时候没有太多体会,但是人家都是这么说 。

2.对于函数指针传参的问题,,我这里利用的reentrant关键字(别的我也不会了)来解决多个参数传入的事情。至于这个怎么正确使用你可以查一查论坛里的帖子 说的很清楚了。。

别的感觉写的也没啥问题,剩下的你自己在捋捋吧,
参考例程并不是对技术参 考手册的补充,而是对技术参 考手册的解释。
技术参 考手册不应该需要参考例程作为补充,而是解释成了参考例程的样子
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:98
  • 最近打卡:2025-04-29 07:45:37

3

主题

74

回帖

358

积分

中级会员

积分
358
发表于 2024-6-25 20:29:03 | 显示全部楼层
_奶*** 发表于 2024-6-25 20:18
你可以思考一下 看看哪里用的不对了,,,

1.动态内存申请,,你这里是正确的,,但是后面用的时候要注 ...

我加了这个reentrant关键字,编译都不通过。报错   *** ERROR L104: MULTIPLE PUBLIC DEFINITIONS  ,搞不懂了。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:7
  • 最近打卡:2025-04-01 23:18:33

15

主题

139

回帖

977

积分

高级会员

积分
977
发表于 2024-6-25 23:05:27 | 显示全部楼层
参考keil c51帮助文件 “Passing in Registers” 一节

C functions may pass parameters in registers and fixed memory locations. A maximum of 3 parameters may be passed in registers. All other parameters are passed using fixed memory locations. The following tables define which registers are used for passing parameters.

Arg Number char,
1-byte ptr int,
2-byte ptr long, float generic ptr
1 R7 R6 & R7
(MSB in R6,LSB in R7) R4—R7 R1—R3
(Mem type in R3, MSB in R2, LSB in R1)
2 R5 R4 & R5
(MSB in R4,LSB in R5) R4—R7 R1—R3
(Mem type in R3, MSB in R2, LSB in R1)
3 R3 R2 & R3
(MSB in R2,LSB in R3)   R1—R3
(Mem type in R3, MSB in R2, LSB in R1)

The following examples clarify how registers are selected for parameter passing.

Declaration Description
func1 (
int a) The first and only argument, a, is passed in registers R6 and R7.
func2 (
int b,
int c,
int *d) The first argument, b, is passed in registers R6 and R7. The second argument, c, is passed in registers R4 and R5. The third argument, d, is passed in registers R1, R2, and R3.
func3 (
long e,
long f) The first argument, e, is passed in registers R4, R5, R6, and R7. The second argument, f, cannot be located in registers since those available for a second parameter with a type of long are already used by the first argument. This parameter is passed using fixed memory locations.
func4 (
float g,
char h) The first argument, g, passed in registers R4, R5, R6, and R7. The second parameter, h, cannot be passed in registers and is passed in fixed memory locations.
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:7
  • 最近打卡:2025-04-01 23:18:33

15

主题

139

回帖

977

积分

高级会员

积分
977
发表于 2024-6-25 23:13:22 | 显示全部楼层
寄存器最多传递3个参数,指的是单字节参数或双字节参数。你这个程序里的参数是通用指针占3个字节,最多只能传递一个参数,这么写必然编译不过。
无标题1.png
我前面已经说过,如果一定要寄存器传两个指针,将3字节通用指针改成2字节指针试试。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:7
  • 最近打卡:2025-04-01 23:18:33

15

主题

139

回帖

977

积分

高级会员

积分
977
发表于 2024-6-25 23:16:45 | 显示全部楼层
QQ6243*** 发表于 2024-6-25 19:31
使用惯了函数指针,指针函数,不用这些代码功能都写不出来。
C51上使用带参的指针函数是没有任何问题的 ...

C51函数指针不是说不能用,你需要知道有什么限制条件。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:7
  • 最近打卡:2025-04-01 23:18:33

15

主题

139

回帖

977

积分

高级会员

积分
977
发表于 2024-6-25 23:43:18 | 显示全部楼层
51单片机的堆栈指针SP为8位,寻址范围只有256字节,所以C51不能像通用C语言那样把函数的局部变量分配在堆栈上。
x86,ARM这些架构,堆栈足够大,局部变量自动分配在堆栈上,函数退出时自动回收。
C51函数的局部变量是用的直接内存地址,类似全局变量那样,所以默认都不可重入。
为了节省内存,编译时会分析函数的调用关系,不存在嵌套关系,不会同时调用的函数,它们的局部变量地址可以复用。
通过指针调用的这种函数,运行时才能知道调用哪个函数,在编译时无法得知调用关系,覆盖分析无效,只能给每个函数分配单独的地址,比较浪费空间。
同样,因为编译时不知道调用哪个函数,自然不知道它们的局部变量分配在哪个地址,也就不能用直接地址传递参数。只可以用寄存器传递有限的参数。

一个函数既有直接调用,还通过函数指针间接调用,这样会有更严重的问题。
例如函数A和函数B,编译器分析它们不存在同时调用的关系,则它们的局部变量可能会分配在相同的地址。如果用函数指针调用了函数B,则有可能破坏掉A的局部变量。


回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:435
  • 最近打卡:2025-04-30 08:43:23

33

主题

2351

回帖

4860

积分

论坛元老

积分
4860
发表于 2024-6-26 08:42:52 | 显示全部楼层
rayr*** 发表于 2024-6-25 20:29
我加了这个reentrant关键字,编译都不通过。报错   *** ERROR L104: MULTIPLE PUBLIC DEFINITIONS  ,搞 ...

你自己的程序你自己去检查啊,方法都说了,我这里测试也都过了,剩下的看你keil C的功底了
参考例程并不是对技术参 考手册的补充,而是对技术参 考手册的解释。
技术参 考手册不应该需要参考例程作为补充,而是解释成了参考例程的样子
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:98
  • 最近打卡:2025-04-29 07:45:37

3

主题

74

回帖

358

积分

中级会员

积分
358
发表于 2024-6-26 18:10:19 | 显示全部楼层
hea*** 发表于 2024-6-25 23:13
寄存器最多传递3个参数,指的是单字节参数或双字节参数。你这个程序里的参数是通用指针占3个字节,最多只能 ...

谢谢老师的指导。
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-2 09:00 , Processed in 0.148275 second(s), 94 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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