LAOXU 发表于 2024-3-20 15:24:42

以上是我改写的 字符串操作 函数库, 上述 加/* */ 的函数, 都需要通过 RAM 传递参数,

有十几个吧~~~

我改写成 通过 R0-R7, SP堆栈传递, 是属于标准的 可重入函数.

LAOXU 发表于 2024-3-20 15:29:25

但需要静态属性 !!!
======================
你这样倒过来倒过去, 都是"伟光正", 没得玩了.

我印像很深, 相信肯定有网友记得, 你老在某贴上说过一句话, 意思是 "C51的函数都是不可重入的, C251的函数都是可重入的,"

杨为民 发表于 2024-3-20 15:32:36

LAOXU 发表于 2024-3-20 15:18
/*--------------------------------------------------------------------------
STRING2.H



(1)为什么我的C51的STRING.H库函数是这样的:


/*--------------------------------------------------------------------------
STRING.H

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

#ifndef __STRING_H__
#define __STRING_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*strcat(char *s1, const char *s2);
extern char*strncat (char *s1, const char *s2, size_t n);

extern char   strcmp(const char *s1, const char *s2);
extern char   strncmp (const char *s1, const char *s2, size_t n);

extern char*strcpy(char *s1, const char *s2);
extern char*strncpy (char *s1, const char *s2, size_t n);

extern size_t strlen(const char *);

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

extern size_t strspn(const char *s, const char *set);
extern size_t strcspn (const char *s, const char *set);
extern char*strpbrk (const char *s, const char *set);
extern char*strrpbrk(const char *s, const char *set);
extern char*strstr(const char *s, const char *sub);
extern char*strtok(char *str, const char *set);

extern char   memcmp(const void *s1, const void *s2, size_t n);
extern void*memcpy(void *s1, const void *s2, size_t n);
extern void*memchr(const void *s, char val, size_t n);
extern void*memccpy (void *s1, const void *s2, char val, size_t n);
extern void*memmove (void *s1, const void *s2, size_t n);
extern void*memset(void *s, char val, size_t n);
#pragma RESTORE

#endif

为什么与你的STRING.H大不相同?你确定你用的你老师的C51是Keil的C51吗?

杨为民 发表于 2024-3-20 15:36:12

LAOXU 发表于 2024-3-20 15:29
但需要静态属性 !!!
======================
你这样倒过来倒过去, 都是"伟光正", 没得玩了.


“你老在某贴上说过一句话, 意思是 "C51的函数都是不可重入的, C251的函数都是可重入的,"”

请把这句话找出来!

LAOXU 发表于 2024-3-20 15:42:55

就算你老关掉所有优化, 但由于 c51内部库函数, 所用的局部(临时)变量, 都使用 data,
只要在各个有冲突的地方, 多调用几次, data爆仓,sp堆栈溢出, 只有 不到 256字节的 data(因为 r1-r7要占用一部分) sp堆栈, 那能玩的转???

杨为民 发表于 2024-3-20 15:43:28

LAOXU 发表于 2024-3-20 15:24
以上是我改写的 字符串操作 函数库, 上述 加/* */ 的函数, 都需要通过 RAM 传递参数,

有十几个吧~~~


你怎么证明Keil的STRING函数库里的函数是不可重入的?你说不可重入就不可重入了?你挑一个在这里证明给我们看,也让我们长长见识!

你发这个帖子不就是想卖弄你,想说你比Keil的专家还聪明,那你就那个实际例子证明一下给大家看看!


杨为民 发表于 2024-3-20 15:44:35

LAOXU 发表于 2024-3-20 15:42
就算你老关掉所有优化, 但由于 c51内部库函数, 所用的局部(临时)变量, 都使用 data,
只要在各个有冲突的地 ...

请你举个实际例子,别瞎说八道!

杨为民 发表于 2024-3-20 15:59:59

本帖最后由 杨为民 于 2024-3-20 16:11 编辑

LAOXU 发表于 2024-3-20 15:29
但需要静态属性 !!!
======================
你这样倒过来倒过去, 都是"伟光正", 没得玩了.

“但需要静态属性 !!!
======================
你这样倒过来倒过去, 都是"伟光正", 没得玩了.”



这不是我倒来倒去,这是C51的原文!这是Keil的官方说明。你讽刺Keil"伟光正",你不想和C51玩,这是你的权利!

我觉得你讽刺我很正常,但你讽刺Keil,那你把自己看得太高了吧,你也太狂妄了吧!

LAOXU 发表于 2024-3-20 16:20:49

就这么一个简单例子, 主程序执行strncpy函数 在加载参数变量时(相当于 OS系统的临界区), 被中断打断了,
当执行中断中的 strncpy函数,在同一 ram地址上, 复盖加载参数变量,
中断返回后, 主程序的 strncpy函数 加载的参数变量, 会被改变!

分析汇编代码, 就能得出这一结论.

chara1[ ]={1,2,3,4,5,6,7,8,9,0};
chara2[ ]={9,8,7,6,5,4,3,2,2,0};
charbb,cc;

void int1(void ) interrupt         1
{
strncpy (bb, a1, 8);
}

void main(void)
{do{
   strncpy (cc, a2, 8);
   }while(1);
}


LAOXU 发表于 2024-3-20 16:34:14

你老是教授会说话, 我向你老向 keil 道歉, 总行了吧.

传统51由于构架原因, 并不适用于跑 OS系统(特别是大容量程序), keil 在 51上推 OS, 问题多多, 后来 251上就直接取消 OS 了.

记得十年前, 网上经常有网友发贴求教 51OS系统运行不稳定易死机. 后来M3/M0流行了, 我想这帮子人都转 M3/M0 去了.

当然, 老姚 后来 推出 stc16/stc32, 又抢回部分客户.
页: 1 [2] 3 4 5
查看完整版本: C51 和 C251 标准库的区别