找回密码
 立即注册
查看: 17|回复: 2

怎样让edata 达到4K?

[复制链接]
  • 打卡等级:偶尔看看I
  • 打卡总天数:12
  • 最近打卡:2026-03-31 15:27:48
已绑定手机

7

主题

32

回帖

109

积分

注册会员

积分
109
发表于 前天 23:21 | 显示全部楼层 |阅读模式
STC32G12K128 说edata有4K, 可是Keil 5 编译edata+hdata=256, 什么意思?  怎样控制这个4K  SRAM的分配?
截图202603302315592092.jpg
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:12
  • 最近打卡:2026-03-31 15:27:48
已绑定手机

7

主题

32

回帖

109

积分

注册会员

积分
109
发表于 昨天 21:54 | 显示全部楼层
是不是edata的最高地址是堆栈,低端编译时显示256,实际超出只要不和堆栈冲突就没事
回复

使用道具 举报 送花

  • 打卡等级:以坛为家III
  • 打卡总天数:846
  • 最近打卡:2026-03-31 00:48:17

12

主题

1342

回帖

7202

积分

论坛元老

积分
7202
发表于 昨天 22:01 | 显示全部楼层
编译edata+hdata=256, 什么意思?


edata+hdata=256 就是edata+hdata用了256位 给堆栈使用

控制这个4K  SRAM的分配 可以在配置中自行添加edata字段




使用Keil C251编译器,Memory Model推荐设置XSmall模式,默认定义变量在edata,单时钟存取访问速度快。
edata建议保留1K给堆栈使用,空间不够时可将大数组、不常用变量加xdata关键字定义到xdata空间。

咨询了tongyiqianwen答复是:
根据 Keil C251 编译器的架构特性,您的理解存在偏差。XSmall 模式并不推荐作为通用设置,且其默认变量存储区并非 edata。
在 Keil C251 中,XSmall 模式主要是为了兼容旧版 Keil C251 V2 编译器而保留的,其默认将变量存储在片内 data 区域。
⚙️ Keil C251 内存模型详解
Keil C251 编译器提供了三种内存模型,用于决定未明确指定存储类型的变量的默认存放位置。

内存模型 (Memory Model)        默认存储区        地址范围                特点
XSmall        data        片内 RAM 低 128 字节        访问速度最快,但空间极其有限。主要用于兼容旧项目。
Small        data        片内 RAM 低 128 字节        最常用且推荐的模式。能生成最高效的代码,适用于绝大多数应用。
Large        xdata        外部 RAM (最高64KB)        变量空间巨大,但访问速度相对较慢,因为需要通过数据指针 (DPTR) 间接寻址。

核心要点与建议
        1-推荐设置:对于新的 C251 项目,通常推荐使用 Small 模式。它在代码效率和易用性之间取得了最佳平衡。
        2-默认存储区:XSmall 和 Small 模式的默认存储区都是 data,而不是 edata。edata 通常指扩展的片内 RAM(如 8052 的 128-255 字节),需要通过 idata 关键字间接寻址访问。
        3-灵活管理内存:无论选择哪种模型,您都可以在代码中显式地使用存储类型关键字(如 xdata, idata, pdata 等)来精确控制特定变量的存放位置,以优化程序性能。
                高频访问变量:如循环计数器,应放在 data 区。
                大型数组/缓冲区:建议用 xdata 关键字显式定义,即使在小模式下,也能将其放至外部 RAM,避免耗尽宝贵的片内 RAM。


直接使用官方的project。rebuild,然后
rebuild输出
Program Size: data=8.0 edata+hdata=257 xdata=0 const=0 code=169


咨询了tongyiqianwen coder 模型,

咨询了coder模型

对于 STC32G 这样的现代增强型 8051 芯片,Keil C251 编译器对 XSmall 模式进行了扩展:
传统 8051:在传统的 8051 架构中,XSmall 模式将未指定存储区的变量放入 data (片内 RAM 低 128 字节)。
现代增强型 8051 (如 STC32G):由于芯片功能强大,内部集成了更多的特殊功能寄存器 (SFR) 和额外的片内 RAM。
编译器会将这部分新增的片内 RAM 视为一个独立的、高效的内存区域,即 edata (Extended Data)。
因此,在 XSmall 模式下,编译器会优先将变量分配到这片 edata 空间中。


hdata:为更大内存而生
hdata 是 Keil C251 编译器为支持更大地址空间的新型 8051 单片机(如 STC32G)而引入的存储类型。
        物理位置:扩展的外部 RAM。
        地址范围:理论上可寻址高达 16MB 的空间(地址 0x000000 - 0xFFFFFF)。
        用途:当您的应用程序数据量巨大,连 64KB 的 xdata 空间都不够用时,就需要使用 hdata 来访问更大的内存区域


为什么会这样?
edata 相对于 xdata 有以下优势:
速度快:访问 edata 的速度远快于访问外部 xdata。
效率高:edata 的寻址方式比 xdata 更高效。
所以,当编译器发现一个变量没有被明确指定存储区时,它会优先选择最快的可用内存空间。
对于 STC32G,这片最快的额外空间就是 edata。这就是为什么您的变量 ledIndex 出现在了 edata 区域。

而data=8.0 到底是什么?
data=8.0 表示的是 程序总共需要的 data 段(片内低 128 字节 RAM)的大小为 8 字节。
这个值不是指某个特定的变量,而是由多个因素共同构成的总和。它主要包括以下几个部分:
系统/运行时开销 (System Overhead):
        编译器和链接器需要为程序的正常运行预留一些空间。例如,一些内部的工作寄存器、临时变量或函数调用时的参数传递空间等,可能会被分配到这里。
中断向量表 (Interrupt Vector Table):
        虽然中断向量本身在 code 区,但处理中断时所需的现场保护(保存 CPU 寄存器)和恢复操作,通常会在 data 区进行,这会占用少量空间。
堆栈 (Stack):
        这是最主要的部分。在 XSmall、Small 等模式下,系统的硬件堆栈指针 (SP) 通常被初始化指向 data 区域。当发生函数调用、中断或使用 push/pop 指令时,数据会被压入和弹出这个位于 data 区的堆栈。链接器会估算一个最小的堆栈空间需求,并将其计入 data 段的总大小。例如,您的 main 函数调用 delay_ms,delay_ms 函数内的局部变量 i 和函数返回地址都会用到堆栈。
被强制分配到 data 区的变量:
        如果您的代码中有 data u8 someVar; 这样的声明,那么 someVar 就会占用 data 区的空间。
🧠 在您程序中的具体体现
        在您提供的这个简单程序中,data=8.0 基本上可以理解为 系统为您的程序分配的、用于函数调用和中断处理的最小堆栈空间。
        ledIndex 变量本身(以及其他未明确指定存储区的变量)并没有进入 data 区,而是被编译器优化到了速度同样很快的 edata 区。
        ledNum 数组被 code 关键字修饰,它存储在程序代码区,不占用 data 或 xdata。
        delay_ms 函数中的局部变量 i 在函数执行期间需要在堆栈上分配空间,这就构成了对 data 区的需求。
💡 总结
        data=8.0 并不是一个具体的变量名,而是链接器计算出的,您的程序在片内低 128 字节 RAM (data 区) 中所必需使用的总空间量。
        在您的程序中,这 8 字节很可能是为函数调用堆栈预留的最小空间,加上少量的系统开销。
回复

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2026-4-1 03:39 , Processed in 0.104407 second(s), 54 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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