找回密码
 立即注册
查看: 4570|回复: 45

C51 和 C251 标准库的区别

[复制链接]
  • 打卡等级:以坛为家I
  • 打卡总天数:312
  • 最近打卡:2025-03-11 13:20:13

54

主题

1327

回帖

5395

积分

荣誉版主

积分
5395
发表于 2024-3-20 10:00:02 | 显示全部楼层 |阅读模式
C51的标准库, 除一些功能简单的函数是可重入的, 其余(约占一半)都是不可重入的函数,

老师言: "C51的LIB都是不可重入." , 由于C51未特别注明 标准库的可重入性, 你把她全部当作不可重入的函数, 也对.

C51的标准库, Keil 对其多次人工优化, 现有 LIB很难再进一步优化了.

----------------------------------------------------------------------------------------------------------------

C251的标准库, 除少量函数是不可重入的(例如 print函数), 其余绝大多数都是可重入的函数,

老师言: "C251的LIB都是可重入." , C251可重入性库函数都特别注明的, 未注明的少量库函数则是不可重入.

C251的标准库, Keil大多数以 C编写, 未对其进行人工优化, 现有 LIB好多地方可再进一步优化.


回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:513
  • 最近打卡:2025-05-01 04:31:49

24

主题

515

回帖

986

积分

荣誉版主

积分
986
发表于 2024-3-20 10:33:38 | 显示全部楼层
前段时间,发现一个非常奇葩的事情:
P10 = !P10;
P10 = ~P10;
在C51编译的结果都是:CPL      0x90.0

而在C251中,P10 = ~P10; ----> CPL      0x90.0
         P10 = !P10; -----> 需要十多个时钟。
回复 支持 反对

使用道具 举报 送花

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

33

主题

2351

回帖

4860

积分

论坛元老

积分
4860
发表于 2024-3-20 10:45:09 | 显示全部楼层
社区*** 发表于 2024-3-20 10:33
前段时间,发现一个非常奇葩的事情:
P10 = !P10;
P10 = ~P10;

需要十多个时钟的那个 是编译成啥了?
参考例程并不是对技术参 考手册的补充,而是对技术参 考手册的解释。
技术参 考手册不应该需要参考例程作为补充,而是解释成了参考例程的样子
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:513
  • 最近打卡:2025-05-01 04:31:49

24

主题

515

回帖

986

积分

荣誉版主

积分
986
发表于 2024-3-20 10:53:44 | 显示全部楼层
十多个时钟有点夸张,看图
捕获.PNG

点评

看起来只执行了三条指令,其中包含一个跳转,总共5个时钟呀,怎么说有十几个?  发表于 2024-3-20 11:25
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:422
  • 最近打卡:2025-05-01 09:54:52
已绑定手机

19

主题

3190

回帖

4866

积分

论坛元老

积分
4866
发表于 2024-3-20 12:09:33 | 显示全部楼层
也就是C251的优化没C51好会浪费更多的存储资源吗
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:312
  • 最近打卡:2025-03-11 13:20:13

54

主题

1327

回帖

5395

积分

荣誉版主

积分
5395
发表于 2024-3-20 14:03:25 | 显示全部楼层
C51编译结果
11.JPG


C251编译结果

112.JPG

结论:
执行

P10 = !P10;  C51优化, C251 则没优化


执行
P20 = ~P20;  两者 优化级相同


回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:16
  • 最近打卡:2025-04-30 08:41:32

105

主题

1215

回帖

1万

积分

荣誉版主

积分
12882
发表于 2024-3-20 14:56:20 | 显示全部楼层
本帖最后由 杨为民 于 2024-3-20 14:58 编辑

“C51的标准库, 除一些功能简单的函数是可重入的, 其余(约占一半)都是不可重入的函数,”

(1)危言耸听!没有证据!
(2)除了“STDIO”库之外,请你举出3个以上C51标准库函数是不可重入函数的例子!

回复 支持 1 反对 0

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:16
  • 最近打卡:2025-04-30 08:41:32

105

主题

1215

回帖

1万

积分

荣誉版主

积分
12882
发表于 2024-3-20 15:11:39 | 显示全部楼层
(1)STDIO库函数有


extern char _getkey (void);
extern char getchar (void);
extern char ungetchar (char);
extern char putchar (char);
extern int printf   (const char *, ...);
extern int sprintf  (char *, const char *, ...);
extern int vprintf  (const char *, char *);
extern int vsprintf (char *, const char *, char *);
extern char *gets (char *, int n);
extern int scanf (const char *, ...);
extern int sscanf (char *, const char *, ...);
extern int puts (const char *);

由于这些含有对串口的操作以及需要额外的内部缓冲器,所以是不可重入的。
(2)下面是MATH函数库:

#ifndef __MATH_H__
#define __MATH_H__

#if defined (__CX2__)
#pragma SAVE
#pragma FUNCTIONS(STATIC)
/* intrinsic functions are reentrant, but need static attribute */
extern int    abs  (int   val);
#pragma RESTORE
#endif

#pragma SAVE
#pragma REGPARMS
extern char  cabs  (char  val);
#if !defined (__CX2__)
extern int    abs  (int   val);
#endif
extern long  labs  (long  val);
extern float fabs  (float val);
extern float sqrt  (float val);
extern float exp   (float val);
extern float log   (float val);
extern float log10 (float val);
extern float sin   (float val);
extern float cos   (float val);
extern float tan   (float val);
extern float asin  (float val);
extern float acos  (float val);
extern float atan  (float val);
extern float sinh  (float val);
extern float cosh  (float val);
extern float tanh  (float val);
extern float atan2 (float y, float x);

extern float ceil  (float val);
extern float floor (float val);
extern float modf  (float val, float *n);
extern float fmod  (float x, float y);
extern float pow   (float x, float y);

#pragma RESTORE

其中这句话“/* intrinsic functions are reentrant, but need static attribute */”的中文翻译为“/*内部函数是可重入的,但需要静态属性*/”

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:312
  • 最近打卡:2025-03-11 13:20:13

54

主题

1327

回帖

5395

积分

荣誉版主

积分
5395
发表于 2024-3-20 15:18:01 | 显示全部楼层
/*--------------------------------------------------------------------------
STRING2.H

String functions.
Copyright (c) 1988-2002 Keil Elektronik GmbH and Keil Software, Inc.
All rights reserved.
--------------------------------------------------------------------------*/

#ifndef __STRING2_H__
#define __STRING2_H__

#ifndef _SIZE_T
#define _SIZE_T
typedef unsigned int size_t;
#endif

#ifndef NULL
#define NULL ((void *) 0L)
#endif

#pragma SAVE
#pragma REGPARMS

extern char *pploadlp (long l, char **p);
extern char *ploadcp (char c, char *s);
extern int  iloadcp (char c, char *s);
extern char cloadcp (char c, char *s);
extern char *ploadp (char *s);
extern int  iloadp (char *s);
extern char cloadp (char *s);

/* extern char *strcat (char *s1, char *s2); */
#define  strcat(dst, src)                                strcat1a ((long)src, dst)
extern char *strcat1a (long dst, char *src);

/* extern char *strncat (char *s1, char *s2, int n); */
  #define  strncat(dst, src, n)                        (!(ACC^ACC) ? ploadp (src) : strncat1 (n, dst))
extern char *strncat1 (int n, char *dst);

extern char strcmp (char *s1, char *s2);    // (char *R0R4R5, char *R1R2R3)
/* extern char strncmp (char *s1, char *s2, int n); */
  #define  strncmp(s1, s2, n)                        (char)(!(ACC^ACC) ? cloadp (s1) : strncmp1 (n, s2))
extern char strncmp1 (int n, char *s2);

extern char *strcpy (char *s1, char *s2);        // (char *R0R4R5, char *R1R2R3); *s2-->*s1
/* extern char *strncpy (char *s1, char *s2, int n); */
  #define  strncpy(dst, src, n)                        (!(ACC^ACC) ? ploadp (dst) : strncpy1 (n, src))
extern char *strncpy1 (int n, char *src);

extern int strlen (char *);

extern char *strchr (const char *s, char c);        // (const char *R1R2R3, char R5)
extern int strpos (const char *s, char c);                // (const char *R1R2R3, char R5)
extern char *strrchr (const char *s, char c);        // (const char *R1R2R3, char R5)
extern int strrpos (const char *s, char c);                // (const char *R1R2R3, char R5)

/* extern int strspn (char *s, char *set); */
#define  strspn(s, set)                                strspn1a ((long)s, set)
extern int strspn1a (long s, char *set);

/* extern int strcspn (char *s, char *set); */
#define  strcspn(s, set)                                strcspn1a ((long)s, set)
extern int strcspn1a (long s, char *set);

/* extern char *strpbrk (char *s, char *set); */
#define  strpbrk(s, set)                                strpbrk1a ((long)s, set)
extern char *strpbrk1a (long s, char *set);

/* extern char *strrpbrk (char *s, char *set); */
#define  strrpbrk(s, set)                                strrpbrk1a ((long)set, s)
extern char *strrpbrk1a (long s, char *set);

/* extern char *strstr  (char *s, char *sub); */
#define  strstr(s, sub)                                strstr1a ((long)sub, s)
extern char *strstr1a (long s, char *sub);

extern char *strtok  (char *str, const char *set);

/* extern char *strtok_s  (char *str, const char *set, char **save_ptr); */
#define  strtok_s(s, set, save_ptr)        (!(ACC^ACC) ? pploadlp ((long)s, (char**)save_ptr) : strtok_s1 (set))
extern char *strtok_s1 (const char *set);

extern char memcmp (void *s1, void *s2, int n);    // (void *R0R4R5, void *R1R2R3, int R6R7)
extern void *memcpy (void *s1, void *s2, int n);   // (void *R0R4R5, void *R1R2R3, int R6R7); *s2-->*s1
extern void *memchr (void *s, char val, int n);           // (void *R1R2R3, char R5, int R6R7)

/* extern void *memccpy (void *s1, void *s2, char val, int n); */                   // *s2-->*s1
  #define  memccpy(dst, src, c, n)                (!(ACC^ACC) ? ploadcp (c, src) : memccpy1 (n, dst))
extern void *memccpy1 (int n, void *dst);                                                                   // *s2-->*s1

extern void *memmove (void *s1, void *s2, int n);  // (void *R0R4R5, void *R1R2R3, int R6R7); *s2-->*s1
extern void *memset  (void *s, char val, int n);   // (void *R1R2R3, char R5, int R6R7)
#pragma RESTORE

#endif


点评

(1)为什么我的C51的STRING.H库函数是这样的: /*-------------------------------------------------------------------------- STRING.H String functions. Copyright (c) 1988-2014 Keil Elektronik GmbH and  详情 回复 发表于 2024-3-20 15:32
请问,你是怎么知道这些函数是不可重入的? 是C51手册(这个是权威)里说的?还是你杜撰的所谓老师说的?还是百度说的? 你怎么证明这些标准库函数是不可重入的?  详情 回复 发表于 2024-3-20 15:24
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:16
  • 最近打卡:2025-04-30 08:41:32

105

主题

1215

回帖

1万

积分

荣誉版主

积分
12882
发表于 2024-3-20 15:24:09 | 显示全部楼层
LAO*** 发表于 2024-3-20 15:18
/*--------------------------------------------------------------------------
STRING2.H

请问,你是怎么知道这些函数是不可重入的?

是C51手册(这个是权威)里说的?还是你杜撰的所谓老师说的?还是百度说的?
你怎么证明这些标准库函数是不可重入的?
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-2 04:16 , Processed in 0.411496 second(s), 111 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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