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, 又抢回部分客户.