发新帖我要提问
12
返回列表
打印

[灌水]初始化 VS 赋值

[复制链接]
楼主: lenglx
手机看帖
扫描二维码
随时随地手机跟帖
21
lenglx|  楼主 | 2007-6-26 13:34 | 只看该作者 回帖奖励 |倒序浏览

呵呵

同意你的这段代码.这样写确实kkk会出现一些问题.

但是...
init()作为一个系统初始化使用的函数,我想不出来kkk会有什么作用.
第一种可能: 你利用kkk作为对调用init()次数的计数,但你上面这段程序显然不是用于这个目的;

第二种可能:你还有其他地方调用init(),而这个调用并不需要使kkk清零.
然而,如果你真有这样的需要,那么是否应当修改init()函数如下:

init(bool is_init)
{
    static kkk = 0;  
    if( is_init )
        kkk = 0;
    //.......
}

main()
{
    init(ture);

    while(1)
    {
        //...
    
        if( Powerdown_Requ )
        {
            powerdown();
            init(true);     
        }
}

other_func()
{
    //....
    init(false);
}
 


 

使用特权

评论回复
22
turmary| | 2007-6-26 18:05 | 只看该作者

个人意见

对于MCU之类的程序存储在Flash中的,
全局变量和局部变量都要有初使化代码(LZ的程序动作)

对于PC之类的,程序从磁盘加载到RAM中的,
全局变量的初使化值就在EXE文件中(LZ的编译器动作)
而非静态局部变量的初使化才有初使化代码(同赋值)

所以我觉得不同的编译器不同环境要具体分析

使用特权

评论回复
23
lenglx|  楼主 | 2007-6-26 19:02 | 只看该作者

to: turmary


也是个人意见:

对于你所说的:"程序存储在Flash中"和"程序从磁盘加载到RAM中" 
这两种情况其实和编译器无必然的关系. 
只不过对于"加载到RAM中执行",由操作系统增加了个"将程序(或者说可执行文件更好?)加载到RAM"的动作而已,没有被加载前,它只是一个"文件"而已,加载到内存并且获得控制权后,它才是一个"程序".而一旦加载完成,就和"程序在FLASH"没什么两样了(当然FLASH和RAM还是有一些区别的,但不关我们现在讨论的主题). 
我且认为你所的"程序在FLASH"真的是指的"程序",而不是"程序文件".
"程序":在系统上电后,能立刻获得控制权,并且运行.
"程序文件",存储在某个存储介质上(比如磁盘,比如FLASH),需要经过某个步骤(或经过操作系统,或根本就是你自己编的一段加载程序)加载到系统内存,然后获得控制权,并开始运行后,它才变成"程序".

另:对于MCU之类的程序存储在Flash中的, 全局变量和局部变量都要有初使化代码(LZ的程序动作)
对于PC之类的,程序从磁盘加载到RAM中的,全局变量的初使化值就在EXE文件中(LZ的编译器动作)
如果C51中有如下语句:   code int  gobal_val = 0x55;  是不是也可以认为"初始化值"在EXE文件(FLASH)中?
 

使用特权

评论回复
24
high| | 2007-6-26 19:57 | 只看该作者

可能因为你做高级语言的,所以会有这些困惑。

1,不要考虑语言差异,c,c++...都是一样的。都是段拷贝。把data段和bss段拷贝到内存,这里面的东西就是初始化值。还有text里面的只读数据也可以视为初始化值(一般由const等特殊关键字产生,关键字视编译器而定)。对应arm来说,
text = ro
data = rw
bss  = zi

2,上面说的是系统程序,对应用程序也是一样的,比如windows,段内容都在程序文件的pe文件头里面

3, 初始化目的就是在运行前得到值。

使用特权

评论回复
25
turmary| | 2007-6-27 01:41 | 只看该作者

回23楼

可能我说的不清楚,

对于LZ的
code int  gobal_val = 0x55;
请看下图,变量确实否在于Flash中,
所以不可更改,变成了常量.

在引用时,用MOVC指令从固定ROM地址(代表变量gobal_val)读取.
而这个地址在烧入程序时,即是0x55

使用特权

评论回复
26
turmary| | 2007-6-27 02:21 | 只看该作者

还有

程序代码

#include <reg52.h>
#include <stdio.h>

code int  gobal_val = 0x55;

main() {
    /*gobal_val = 0x33;*/
    int i = 0x33;
    i = gobal_val;
}


请看下图

在ROM地址0003-0006是
int i = 0x33;对应的代码
局部变量i是放在R6R7中的.

ROM地址0007-0011是 i = gobal_val对应的代码
即从ROM地址001E-001F赋值到R6R7,
所以gobal_val变量的存储地址是C:001E

再看看在C:001E-C:001F中存放的就是0x0055 
(这也让我认识到Keil C51是高字节低地址)

而在整个main()对应的代码(ROM地址0003-0011)
都找不到gobal_val初使化的影子

那么这个ROM中的0x0055就是程序的一部分

按LZ的说法
程序中0x0055的生成编译器的动作
而i的初使化赋值即是指令动作.

相应于PC的EXE文件,
全局变量也是存在于EXE文件中的.
因为放入了RAM中,是可以赋值的.
(从这个角度看LZ把EXE文件比做FLASH还是很贴切的,^_^)

使用特权

评论回复
27
马合店村| | 2012-1-28 22:05 | 只看该作者
声明后马上幅值

使用特权

评论回复
28
llp133| | 2012-1-28 22:30 | 只看该作者
intX=1与INTX=A  A=1有着本质上的区别

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则