1046|9

343

帖子

0

资源

一粒金砂(中级)

问个傻傻的问题 [复制链接]

一直没太明白keil 编译时全局变量是存放在哪个区的,今天在程序里面试了下,定义几个全局变量后,code区的大小一直未变,倒是Xdata区的变大了。我的理解是这样的,在编译的时候,不也应该在代码区给全局变量分配地址吗,这样程序运行过程中才可以找得到这个变量。如果定义在xdata区,又因为xdata不是属于ram区吗,掉电后不是会丢失?

现在全迷糊了,以前没考虑过这么多,乱了!!!

此帖出自51单片机论坛

回复

1万

帖子

143

资源

版主

变量不管是什么类型都是处于RAM中,Code区是程序代码存放的地方,只能定义程序区的常量。XData是外置内存区,定义方法也与内置内存区不同,多了个X。

51的存储器分程序存储器(ROM)、内部RAM和外部RAM,现在不少型号集成了外部RAM,虽然在片内,但程序的定义上还是“外部”。

点评

ena
恩,是的。迷糊的是ram区掉电不保存数据,这些全局变量是怎么存在的?上电后又是怎么恢复的?  详情 回复 发表于 2020-6-14 07:57
个人签名上传了一些书籍资料,也许有你想要的:http://download.eeworld.com.cn/user/chunyang

回复

343

帖子

0

资源

一粒金砂(中级)

chunyang 发表于 2020-6-13 23:32 变量不管是什么类型都是处于RAM中,Code区是程序代码存放的地方,只能定义程序区的常量。XData是外置内存区 ...

恩,是的。迷糊的是ram区掉电不保存数据,这些全局变量是怎么存在的?上电后又是怎么恢复的?

点评

建议还是先弄清楚定义。  详情 回复 发表于 2020-6-14 22:25
不是那么理解的, 1. 全局变量当然可以是在ram里边的,只是在程序运行期间,很多函数都是可以访问的。这个主要是编译器的行为, 2. 与之对应的局部变量,局部变量一般是放在CPU寄存器中,R0-R7,或者cpu ram  详情 回复 发表于 2020-6-14 09:54

回复

1500

帖子

2

资源

纯净的硅(高级)

8051的存储区,分为四个区xdata、idata、xdata、code

 data:固定指前面0x00-0x7F的128个RAM,可以用acc直接读写,速度最快,生成的代码也最小。
 idata:固定指前面0x00-0xFF的256个RAM,其中前128和data的128完全相同,只是访问的方式不同。
 xdata:外部扩展RAM。
 code:ROM。

程序中可变的程序变量必须保存在除code以外的RAM区域。xdata、idata、xdata的区别是访问速度不同。

在编程时常量和只读变量放在code区,节省ram空间。

你说的全局变量有两种可能,一种是只读的放在code中的,另种是在ram中的,如果在ram中有初值,在程序上电开始时由rom程序执行后赋予的初值。程序中尽可能的使用局部变量,而不使用静态变量和局部变量


回复

1万

帖子

15

资源

版主

RAM区都是上电初始化的,现往RAM里调数据

个人签名http://shop34182318.taobao.com/
https://shop436095304.taobao.com/?spm=a230r.7195193.1997079397.37.69fe60dfT705yr

回复

1965

帖子

8

资源

五彩晶圆(初级)

ena 发表于 2020-6-14 07:57 恩,是的。迷糊的是ram区掉电不保存数据,这些全局变量是怎么存在的?上电后又是怎么恢复的?

不是那么理解的,

  • 1. 全局变量当然可以是在ram里边的,只是在程序运行期间,很多函数都是可以访问的。这个主要是编译器的行为,
  • 2. 与之对应的局部变量,局部变量一般是放在CPU寄存器中,R0-R7,或者cpu ram。函数调用的时候,会将当前的R0-R7压栈,再去调用其他函数,其他函数可以使用R0-R7存放局部变量,也可以访问全局变量,当函数调用结束后,会做弹栈操作,恢复函数调用前CPU寄存器的变量,主函数可以继续进行访问,此时局部变量作用就消失了,
  • 3. 全局变量是如何访问并且有初始化值,这个是编译器行为,定义了一个全局变量,如果后续有操作的的话,编译器会为这个变量申请一个ram中的地址,其他地方使用这个变量,编译器会保证每次数据的操作都是在这个地址上,如果没有操作,定义的变量可能就优化掉了。如何分配初始值,这个是在生成bin文件,或者hex文件时候,在该地址上分配为这个值。bin文件可以认为是ram一一对应的一张表,bin文件用二进制打开,你看到的二进制数据,比如ram从0x0000~~0x3FFF,16k空间,那么bin文件,从0x0000~0x3FFF的位置的数据下载到ram中0x0000~0x3FFF,是一模一样的。hex文件同理,只不过是用文本的形式记录一下ram中的数据应该是什么,可以查一下intel hex标准。所以你定义全局变量其实code区并不会增加,初始化和分配地址的动作是编译器的行为。
  • 4. 此时如果程序软复位,不断电,全局变量一般是不会被重置的,如果修改过,那么也是保持为修改后的值,如果需要重置可以通过修改startup_s.a那个汇编文件,这个文件做的一件事就是程序PC指针指向0000h开始地址,执行的一段初始化cpu ram和寄存器的小程序,然后才会跳向main函数所在的位置执行main函数。
  • 5. 上边老师也说了,现在的51说是片外ram,其实大部分的sram都是集成在同一个芯片上的,只不过51的cpu需要使用片外的指令才能访问到,比如movx指令等等
  • 6. 可以研究一下生成bin文件,反汇编,或者keil应该也是会有反汇编的窗口,跟着汇编的执行顺序和c程序去对照,很多就清楚了。
  • 7. 最后你说掉电保存的那个是eeprom或者flash这类的结构,才可以。

点评

ena
恩,知道了!另外想再问个问题,如何将一数组定义到falsh区的固定地址,并初始化?在网上搜的是可以定义,但不能初始化,那也没什么意义。谢谢了!  详情 回复 发表于 2020-6-14 16:19
个人签名坐而言不如起而行

回复

343

帖子

0

资源

一粒金砂(中级)

wsmysyn 发表于 2020-6-14 09:54 不是那么理解的, 1. 全局变量当然可以是在ram里边的,只是在程序运行期间,很多函数都是可以访问 ...

恩,知道了!另外想再问个问题,如何将一数组定义到falsh区的固定地址,并初始化?在网上搜的是可以定义,但不能初始化,那也没什么意义。谢谢了!

点评

这种问题查编译器手册是最靠谱的,因为别人告诉你的答案未必是对的。  详情 回复 发表于 2020-6-14 18:17

回复

5980

帖子

209

资源

版主

如果你定义全局非0变量,肯定是要在ROM区存放其初值的,但是算不算到code区就不太清楚了

个人签名

EEWORLD开发板置换群:309018200,——电工们免费装β的天堂,上班摸鱼场,释放压力好地方!商家勿入!加群暗号:喵


回复

5980

帖子

209

资源

版主

ena 发表于 2020-6-14 16:19 恩,知道了!另外想再问个问题,如何将一数组定义到falsh区的固定地址,并初始化?在网上搜的是可以定义 ...

这种问题查编译器手册是最靠谱的,因为别人告诉你的答案未必是对的。

个人签名

EEWORLD开发板置换群:309018200,——电工们免费装β的天堂,上班摸鱼场,释放压力好地方!商家勿入!加群暗号:喵


回复

1万

帖子

143

资源

版主

ena 发表于 2020-6-14 07:57 恩,是的。迷糊的是ram区掉电不保存数据,这些全局变量是怎么存在的?上电后又是怎么恢复的?

建议还是先弄清楚定义。

个人签名上传了一些书籍资料,也许有你想要的:http://download.eeworld.com.cn/user/chunyang

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

最新文章 更多>>
    关闭
    站长推荐上一条 1/9 下一条

    About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

    站点相关: 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

    北京市海淀区知春路23号集成电路设计园量子银座1305 电话:(010)82350740 邮编:100191

    电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2021 EEWORLD.com.cn, Inc. All rights reserved
    快速回复 返回顶部 返回列表