_奶咖君_ 发表于 2024-6-25 20:18:01

rayrakey 发表于 2024-6-25 18:04
就是这样,我晕我现在更懵了,尴尬了。

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

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

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

别的感觉写的也没啥问题,剩下的你自己在捋捋吧,

rayrakey 发表于 2024-6-25 20:29:03

_奶咖君_ 发表于 2024-6-25 20:18
你可以思考一下 看看哪里用的不对了,,,

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

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

health 发表于 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.

health 发表于 2024-6-25 23:13:22

寄存器最多传递3个参数,指的是单字节参数或双字节参数。你这个程序里的参数是通用指针占3个字节,最多只能传递一个参数,这么写必然编译不过。

我前面已经说过,如果一定要寄存器传两个指针,将3字节通用指针改成2字节指针试试。

health 发表于 2024-6-25 23:16:45

QQ624353765 发表于 2024-6-25 19:31
使用惯了函数指针,指针函数,不用这些代码功能都写不出来。
C51上使用带参的指针函数是没有任何问题的 ...

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

health 发表于 2024-6-25 23:43:18

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

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


_奶咖君_ 发表于 2024-6-26 08:42:52

rayrakey 发表于 2024-6-25 20:29
我加了这个reentrant关键字,编译都不通过。报错   *** ERROR L104: MULTIPLE PUBLIC DEFINITIONS,搞 ...

你自己的程序你自己去检查啊,方法都说了,我这里测试也都过了,剩下的看你keil C的功底了

rayrakey 发表于 2024-6-26 18:10:19

health 发表于 2024-6-25 23:13
寄存器最多传递3个参数,指的是单字节参数或双字节参数。你这个程序里的参数是通用指针占3个字节,最多只能 ...

谢谢老师的指导。
页: 1 2 [3]
查看完整版本: 51单片机函数指针问题