变量的声明定义

来源:互联网 发布:牛津 朗文 知乎 编辑:程序博客网 时间:2024/04/30 09:49

    在诸如C语言等高级语言中,当一个变量(符号)定义时,会有两件事发生。首先,编译器会在程序内存中留下足够的空间来保存该变量(符号)的值。第二步,编译器在符号表中创建一个入口,这个入口保存着上一步保留下的保存变量的值的地址。例如:
    int gintl = 1000;
    编译器首先申请一块int类型大小的内存块,假设申请的内存块地址是0x00200070。编译器在符号表中创建符号表时,申请的内存块的地址0x00200070就会保存在符号表中。当使用变量时,首先会在符号表是查找名为"gintl"的符号,通过该符号获取保存该变量值的地址,对该地址的内容进行读取或写入操作就可以读取该变量的值或修改该变量的值。值得一提的是关于指针的操作。例如:
    int *ptr = &gintl;
    对于指针变量ptr来说,按照上述步骤申请内存块以及创建符号表入号。对于初始化的值来说,在符号表中查找'gintl',找到后把符号表中的值0x0020070复制到ptr相关的内存块中。在链接脚本中,定义一个变量时,只在符号表中创建符号表入口,并且把值300保存在符号中。
    foo = 300;
    因此,我们无法在C语言等高级语言中访问foo,因为在链接脚本中定义该变量时并没有为该变量申请内存,该变量只有地址而没有值。我们可以访问它的地址。在链接脚本中,定义的变量就只是用来标识下地址而不是用来修改内存中的数据的。如在链接脚本中定义一个变量和C语言中一样,申请内存块并把值写入内存块中,这样就更改了内存中的数据,并非我们所愿。

用nm命令可查看程序的符号表,可以看出两者的不同。第一列是符号值,第二列是符号类型,第三列是符号名。如下:

 

001003ac t BOARD_GetRemap
00100430 T BOARD_RemapRam
001001a4 T LowLevelInit
0010046c T _efixed
00200074 D _erelocate
00200074 N _ezero
00100000 T _sfixed
00200000 D _srelocate
00204000 A _sstack
00200074 N _szero
00200010 d dataAbortVector
0010018c T defaultFiqHandler
00100198 T defaultIrqHandler
00100180 T defaultSpuriousHandler
00200074 A end
00100000 T entry
0020001c d fiqHandler
0020001c d fiqVector
00200070 D gintl
00200020 d irqHandler
00200018 d irqVector
001000a0 T main
0020000c d prefetchAbortVector
00200014 d reservedVector
00100000 t resetHandler
00200000 d resetVector
00200008 d swiVector
00200004 d undefVector

原创粉丝点击