搜索
bottom↓
回复: 14

请教一个高级语言具体实现变量定义的问题?(不知道我的表述是否正确,请大家帮我解答一个

[复制链接]

出0入0汤圆

发表于 2011-6-10 20:44:13 | 显示全部楼层 |阅读模式
在高级语言中,比如C语言,我们通常会定义一些全局变量或者局部变量,我的问题是,当我们定义一个变量的时候,芯片具体是怎么实现的。这个变量被存储到FLASH里还是BUF里还是RAM里?当我们再次使用它的时候,芯片又是怎么具体实现而找到它的。这个可能涉及到数据结构和编译解释等问题,我不知道我表述的是否清楚,请大侠帮忙解答!谢谢!
最好能越详细越好,不胜感激!

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

 楼主| 发表于 2011-6-10 21:02:53 | 显示全部楼层
我再弱弱的问一句,定义的变量有数量限制吗?如果有,依据是什么?芯片的资源如何分配的?是否有最合理的方案?
例如一个芯片FLASH64K  无ROM  32KRAM 128BUF,定义变量的时候机器码实现的功能是怎样的,空间如何提供的等等。

出0入0汤圆

发表于 2011-6-10 21:12:33 | 显示全部楼层
我猜,楼主一定没用汇编写过程序吧?如果没有,建议你使用汇编写一些程序,然后,你就明白了。

出0入0汤圆

 楼主| 发表于 2011-6-10 21:13:17 | 显示全部楼层
我自己的分析是这样,首先定义的变量存储的位置肯定不在FLASH,因为变量掉电即丢,所以它肯定是在RAM或者BUF里。其次,定义的变量除非特殊定义,肯定都会存储在动态变化的位置上,所以机器码肯定在编译的时候直接给一个地址和预留空间,然后赋值也好,调用也好,直接到那个地址上去取。第三,这个变量可能要在程序执行的过程中变换地址,因为很有可能其他复杂算法占用的资源占用了整个RAM或者BUF,这里就有了问题,如果变量要调到其他的位置上去,那调到哪里去?这个时候是否要考虑一些重要的设置?而在调用这个复杂算法的时候,芯片(芯片在这里可能不恰当,应该叫做核心程序吧~~)怎么知道RAM或者BUF里有一个变量不能冲掉,而应该先保存?这又回到了刚才的那个问题,怎么保存,是否要整块保存?还是有其他设置?
还是我这么思考压根就是错误的,请大侠指点!

出0入0汤圆

 楼主| 发表于 2011-6-10 21:14:35 | 显示全部楼层
回复【2楼】WithSword 倚剑
-----------------------------------------------------------------------

您好!能否指点一下?

出0入0汤圆

 楼主| 发表于 2011-6-10 21:17:51 | 显示全部楼层
回复【2楼】WithSword 倚剑
-----------------------------------------------------------------------

而且我一直用汇编写程序,不知道怎么定义变量,我BC地问一句:汇编里可以定义变量吗?

出0入0汤圆

 楼主| 发表于 2011-6-10 21:23:19 | 显示全部楼层
本人菜鸟,请大侠指点迷津~~

出0入0汤圆

发表于 2011-6-10 21:26:58 | 显示全部楼层
那你看过反汇编没?先用C写一段很简单的程序,然后去看它被编译后的汇编代码。简单来说,定义一个全局变量,就是对确定的地址操作。定义一个局部变量,有两种可能,第一种就是对确定的Register进行操作,另一种就是在堆栈中,但是在堆栈中的位置也是确定的。因此,变量其实就是对确定的地址进行操作而已。至于什么new/delete、malloc/free等动态内存分配,机制要复杂一些,但归根结底,其实最后也是对确定的内存或者寄存器进行操作的。有些汇编语句是支持定义变量的,但是被编译成机器码后,其实也是对确定的地址进行操作而已。


个人愚见。

出0入0汤圆

发表于 2011-6-10 21:29:22 | 显示全部楼层
全局变量和静态的局部变量分配在RAM里面中,局部变量一般分配在buf或者stack中,其实buf和stack也是在RAM里面。stack通过sp指针访问。buf可以快速访问。

出0入0汤圆

 楼主| 发表于 2011-6-10 21:53:07 | 显示全部楼层
回复【7楼】WithSword 倚剑
-----------------------------------------------------------------------

谢谢您!我没有看过反汇编。现在只是在臆断。:)所以如果有傻傻的问题请您谅解。
我在思考,只是在思考。
首先,针对局部变量。因为是局部变量,所以个数应该不会很多,但是也要考虑空间大小的问题。核心程序既可以把局部变量放到堆栈,也可以把局部变量放到寄存器,但是我觉得正好和你描述的相反,放到寄存器里的局部变量的地址是固定的,放到堆栈里的局部变量的位置是变化的。我们要时刻记录堆栈里的局部变量已经压栈压到某个位置了,堆栈的操作比较灵活,赋值或者判断的时候完全可以复制一个一模一样的局部变量到栈顶操作,但是像我之前所说的,压栈压到哪了必须要核心程序记录,这个怎么记录?如果局部变量在寄存器,那寄存器是不是一定要专用的?如果是通用寄存器的话,是否会被其他操作占用资源而冲掉数据?而且很多芯片的寄存器不是很多,这个资源很宝贵。
其次,针对全局变量。如果是一个确定的地址,我不知道它占用的是BUF还是RAM还是寄存器还是堆栈,是不是定义了全局变量之后地址就一直固定不动了?那全局变量很多的情况下会占用很多资源的,怎么保证资源的有效性和可利用性?而且一个全局变量是可以让局部变量覆盖的,这时的局部变量有什么特殊的设置。
附加一个问题,一般的程序设计中可定义的全局变量和局部变量有多少空间?视什么而定?

出0入0汤圆

 楼主| 发表于 2011-6-10 21:59:15 | 显示全部楼层
回复【8楼】fjcqv
-----------------------------------------------------------------------

谢谢您!我不大理解,什么叫“其实buf和stack也是在RAM里面”。“全局变量和静态的局部变量分配在RAM里面中”,那地址是固定的吗?“局部变量一般分配在buf或者stack中”,您认为什么情况该放到BUF,什么情况下该放到STACK中?我知道stack通过sp指针访问,但关键是多个变量存储在stack中时,而且stack也是要参与计算的,所以地址不断地在变化,我们是否要让每一个变量的sp指针都实时地变化?

出0入0汤圆

发表于 2011-6-11 11:30:22 | 显示全部楼层
1。至于你说的局部变量在堆栈中,其实也是固定的。它确实可以很随意的向堆栈中压入和取出数据,但是当你压入一个数据时,你下一次取出的就是这个数据。如果你同时压入两个数据A和B,那么当你要取出A时,就要利用栈顶指针的地址再依移数据B所占的空间,然后再取出A。这些工作编译器都帮你弄好了,如果是你自己用汇编写的话,偏移地址你都得自己算。所以这样说来,其实局部变量在堆栈中的地址也是确定的;虽然不同时间压入的同一个数据可能会存在不同的地方,但是每一次压入的数据在堆栈中都是固定的;
2。全局变量定义之后,就会一直固定不变了。至于你所说的BUF,我不太理解。但它确实是固定在RAM中的某一个地方的,而且,当你定义一个全局变量,而且编译器帮它分配好一个地址后,那么那个地址就是它专有的了。全局变量越多,占用的内存当然越大。一个有效的证据是,编译器一般会告诉你当前占用了多少RAM,当你定义一个全局变量时,这个数值会增加,而当你定义一个局部变量时,这个数据一般都不会增加。至于保证资源的有效利用,一个好的程序员不会无缘无故定义一些可有可无的全局变量的。只要在必要的情况下才定义全局变量,一部分只在本函数内使用但是不能丢失的信息,可以在函数内用static修饰,其它的,定义成局部变量吧。至于你说的全局变量让局部变量覆盖,如果直接用高级语言来写是不现实的。因为全局变量和局部变量根本就不在一个存储区。局部变量一般只存在于寄存器或者堆栈中,而全局变量一般在RAM中的静态存储区。一种可能的实现方法时,当你用到局部变量时,不要去定义它,而是使用已经定义好的全局变量。但不管从哪方面来说,这都不是一种好的做法。因此,还是建议当需要使用时才定义全局变量,其它的使用局部变量吧。


个人愚见。

出0入0汤圆

 楼主| 发表于 2011-6-11 21:04:45 | 显示全部楼层
回复【11楼】WithSword 倚剑
-----------------------------------------------------------------------

非常非常感谢!如果有新问题再向您请教!

出0入0汤圆

发表于 2011-6-11 22:06:18 | 显示全部楼层
回复【10楼】robin45853258 阿奔
-----------------------------------------------------------------------
1、什么叫“其实buf和stack也是在RAM里面”?
局部变量一般分配在buf或者stack中”,您认为什么情况该放到BUF,什么情况下该放到STACK中?
2个问题放一起:
拿mega128举个例子
32 Registers :$0000 - $001F
other Registers:$0020 - $00FF
Internal SRAM :$0100 - $10FF

32 Registers就是我说的buf,而stack栈 就是从Internal SRAM 的后面开始的。

再拿STM8的RAM说明下,0-0f作为虚拟寄存器(即我所说的buf)。1个字节汇编语言可以快速访问,栈同样定义在ram的最后面。

编译器在处理时局部变量时,先使用buf,buf分配不够使用栈。这样可以使得编译后的函数块速度最快。

2、“全局变量和静态的局部变量分配在RAM里面中”,那地址是固定的吗?
地址都是固定好的。

3、关于的局部变量在堆栈的地址,应该叫做相对sp指针固定的。
比如进入func函数后,堆栈指针为sp,func函数中定义的unsigned char b[100],可能对应sp+x----sp+x+99
x是b[0]对于sp指针的偏移量。

出0入0汤圆

 楼主| 发表于 2011-6-12 16:42:36 | 显示全部楼层
回复【13楼】fjcqv
-----------------------------------------------------------------------

万分感谢!谢谢两位高人指点迷津!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-6-4 14:27

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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