zqf441775525 发表于 2022-3-8 11:34:29

咨询局部变量定义为xdata的问题

如题:
我们知道局部变量都是放在堆里的,堆默认是data区。
xdata是放在外部RAM区。

如果我在函数内部定义一个局部变量:u8 xdata i;
那么这个i是放在哪儿的?会不会出错?函数结束后i占用的地址是否会被释放?

ackyee 发表于 2022-3-8 13:11:15

本帖最后由 ackyee 于 2022-3-8 13:13 编辑

STC 中的xdata 是放在 内部的一个 RAM区 但是这个RAM区对51核来说是外部了

stc51核内部有 256字节 ram
其中 idata是定义到128-255   
不定义任何标志是0-127

是否释放是由你的软件 还有代码决定的

zqf441775525 发表于 2022-3-8 13:52:32

ackyee 发表于 2022-3-8 13:11
STC 中的xdata 是放在 内部的一个 RAM区 但是这个RAM区对51核来说是外部了

stc51核内部有 256字节 ram   ...
(引用自2楼)

STC的xdata虽然是内部的,实际上它仅仅是叠封在单片机里面而已,访问还是用MOVX访问的。

比如这个函数:
void temp(void)
{
        u8 xdata Cnt;
        u8 i;
        ....
}
局部变量i一定是放在堆里面的,堆应该是0-127地址之间,而且函数执行完之后i占用的这个地址会被释放。
但是用xdata修饰的Cnt会被放在哪儿?是放在堆里还是放在用MOVX访问的xdata区域?如果放在堆里,这个地址应该会被释放,如果放在xdata区域,这个地址是否还会被释放?

Doding 发表于 2022-3-8 14:13:40

zqf441775525 发表于 2022-3-8 13:52
STC的xdata虽然是内部的,实际上它仅仅是叠封在单片机里面而已,访问还是用MOVX访问的。

比如这个函数: ...
(引用自3楼)

这是51,局部变量都是静态局部变量,函数调用前已经分配好RAM空间,函数执行完了也不会释放。

vuo50z 发表于 2022-3-8 14:57:29

51和现代的单片机不一样,硬件堆栈太小,局部变量也是静态分配的。编译器会分析函数的调用关系,决定哪些局部变量不会同时使用,然后合并。用“reentrant”关键字修饰的函数,或者定义全局可重入,则编译器会用软件模拟一个堆栈,这样就和现代单片机一样了,只是效率不高。

polarbear 发表于 2022-3-8 16:02:21

听说STC32堆栈引入了EDATA,解决了困扰楼主多年的难言之忍

zqf441775525 发表于 2022-3-8 16:22:49

vuo50z 发表于 2022-3-8 14:57
51和现代的单片机不一样,硬件堆栈太小,局部变量也是静态分配的。编译器会分析函数的调用关系,决定哪些局 ...
(引用自5楼)

学习了,多谢

qinxg 发表于 2022-3-9 09:44:33

51没有SP偏移量寻址, 里面的局部变量的地址时固定的. 我跟踪过

小李非刀 发表于 2022-3-9 14:51:03

不管是局部还是全局变量,定义时指定为xdata,则一定会分配在xdata,如果是局部变量,则KEIL一样会做覆盖分析,原则同256字节data,只是变量位置不同。

szxszx 发表于 2022-3-10 08:15:17

小李非刀 发表于 2022-3-9 14:51
不管是局部还是全局变量,定义时指定为xdata,则一定会分配在xdata,如果是局部变量,则KEIL一样会做覆盖分 ...
(引用自9楼)

能否详细讲解一下data、idata、pdata、xdata用法,以及keil软件中Option for Target---Memory Model中:Small、Compact、Large的关系,谢谢

rei1984 发表于 2022-3-10 09:09:51

szxszx 发表于 2022-3-10 08:15
能否详细讲解一下data、idata、pdata、xdata用法,以及keil软件中Option for Target---Memory Model中:S ...
(引用自10楼)

同问这个问题

saccapanna 发表于 2022-3-10 11:01:32

堆和栈是不同的,严格来说,没有 static 修饰的局部变量是放在栈里面的,函数返回后就释放了。
十多年不用 51 核了,不知道 51核的处理机制。

1a2b3c 发表于 2022-3-10 11:07:43

如果定义时修饰了 XDATA 那么肯定这个变量是在 XDATA区域操作 ,而不管这个变量是局部还是全局或者啥啥的,
但是覆盖与否,我个人觉得一个是和程序关系很大,比如你的整个工程的变量使用情况,可能不会覆盖,也可能会覆盖,
我之前有个例子就是,我在函数中使用了一个局部变量,本来我本意是想作为一个局部静态变量的,相当于记录一下这个函数被调用了多少次,结果写代码的时候写成了普通的,没有加 static 修饰,结果运行一切正常。后来完善代码的时候发现了这个问题,增加了static修饰,结果编译和运行结果完全一样,后来查看汇编以及其它东西,发现因为程序相对简单,所使用的临时变量也好,或者静态变量也好,实际上都完全足够把每个变量都作为全局变量来使用,所以也就不存在覆盖了。但是如果程序复杂点,就完全不一样了

Doding 发表于 2022-3-10 11:22:42

本帖最后由 Doding 于 2022-3-10 11:24 编辑

szxszx 发表于 2022-3-10 08:15
能否详细讲解一下data、idata、pdata、xdata用法,以及keil软件中Option for Target---Memory Model中:S ...
(引用自10楼)

这些网上有资料,可以搜索看看。
data是7F以下的片上ram,可以acc直接操作的。
idata是要用取地址方式访问的。
pdata没用过。
xdata是片外的,要用间接寻址方式访问,就是要用到DPTR。

按我的理解,
small是变量优先放内部ram,内部不够要自己定义哪些变量放外部ram。
compact也是变量优先放内部ram,可用的范围增加到256B,再多的还是要自己定义位置,我没用过这种模式,不知道理解的对不对。
large默认放外部ram,变量默认都是xdata的,全用间接寻址方式访问,速度最慢,但没内存容量限制。我现在的程序简单,对速度要求不高,这种模式比较省心。
页: [1]
查看完整版本: 咨询局部变量定义为xdata的问题