C程序编译之函数调用与全局变量
2010-04-19 08:31
417 查看
C程序编译之函数调用与全局变量
1. 函数调用
下图为同一文件内函数调用的C程序与反汇编:
处位置为调用DelayNs函数的反汇编,[0xebffffe2]为指令的机器码值,0x00000310为该指令的存储位置(PC值),根据跳转指令的说明,当执行该指令时,PC将跳转到距离当前PC偏移的位置上,偏移量为 0x00000310+8+(0xffffffe2<<2) = 0x00000310-0x70=0x000002a0。而0x000002a0即为DelayNs函数的地址,所以同一文件内函数的调用为偏移量,这样当存储指令的地址变化了指令的机器码也是相同的。如下图所示:
2. 全局变量
下图为全局变量global_a及DISP_TAB[]的c程序与反汇编:
(1)处为将global_a的值赋给寄存器R2的汇编指令,指令机器码[0xe59f2050]的意思为:将基址寄存器中存储的数据读入到目标寄存器,目标寄存器为R2,源寄存器为R15(PC)+8+0x50=0x00000338处的值及(2)处的数据为0x81000000。而0x81000000为global_a变量的存储位置。
编译器在编译时,将为全局变量创建一个在程序中的位置,位置定义可以使用DCD来占据程序空间,该位置存储着全局变量的实际存储地址。当该变量存储地址变化时,编译器只需修改程序空间中DCD的数据即可。
以上所说的内容都是在程序的CODE代码段,而全局变量的初始值在程序的DATA段中,编译器一般将程序的全局变量的数据段放在代码段的后面,如下图所示:
红框的数据即为global_a全局变量的初始值,程序开始运行时,全局变量的初始值在程序中,所以需要把全局变量的数据搬移到变量实际的存储地址。
所以必须有一段程序在没用到全局变量之前执行该功能,该程序一般是在跳转到Main函数之前完成的。而集成开发工具,在编译连接指令时帮助用户完成了数据段的搬移,用户感觉不到。
这样程序代码段中包含全局变量的正确的位置,而全局变量的初始值也已经搬移到正确的位置,所以程序执行无误。
1. 函数调用
下图为同一文件内函数调用的C程序与反汇编:
处位置为调用DelayNs函数的反汇编,[0xebffffe2]为指令的机器码值,0x00000310为该指令的存储位置(PC值),根据跳转指令的说明,当执行该指令时,PC将跳转到距离当前PC偏移的位置上,偏移量为 0x00000310+8+(0xffffffe2<<2) = 0x00000310-0x70=0x000002a0。而0x000002a0即为DelayNs函数的地址,所以同一文件内函数的调用为偏移量,这样当存储指令的地址变化了指令的机器码也是相同的。如下图所示:
2. 全局变量
下图为全局变量global_a及DISP_TAB[]的c程序与反汇编:
(1)处为将global_a的值赋给寄存器R2的汇编指令,指令机器码[0xe59f2050]的意思为:将基址寄存器中存储的数据读入到目标寄存器,目标寄存器为R2,源寄存器为R15(PC)+8+0x50=0x00000338处的值及(2)处的数据为0x81000000。而0x81000000为global_a变量的存储位置。
编译器在编译时,将为全局变量创建一个在程序中的位置,位置定义可以使用DCD来占据程序空间,该位置存储着全局变量的实际存储地址。当该变量存储地址变化时,编译器只需修改程序空间中DCD的数据即可。
以上所说的内容都是在程序的CODE代码段,而全局变量的初始值在程序的DATA段中,编译器一般将程序的全局变量的数据段放在代码段的后面,如下图所示:
红框的数据即为global_a全局变量的初始值,程序开始运行时,全局变量的初始值在程序中,所以需要把全局变量的数据搬移到变量实际的存储地址。
所以必须有一段程序在没用到全局变量之前执行该功能,该程序一般是在跳转到Main函数之前完成的。而集成开发工具,在编译连接指令时帮助用户完成了数据段的搬移,用户感觉不到。
这样程序代码段中包含全局变量的正确的位置,而全局变量的初始值也已经搬移到正确的位置,所以程序执行无误。
相关文章推荐
- 我的第一个ffmpeg程序(编译及调用ffmpeg函数)
- C++程序运行时内存布局之----------局部变量,全局变量,静态变量,函数代码,new出来的变量
- VC6.0上编译的程序使用不调用全局对象的析构函数
- jquery ajax done 函数 异步调用方法中不能给全局变量赋值的原因及解决办法
- JS预编译对全局变量和命名函数的处理
- VC6.0下调用Dll文件提供的函数接口和全局变量
- 在C++ 程序中调用被 C编译器编译后的函数,为什么要加 extern “C”声明?
- 使用JNIEnv全局变量调用FindClass()等函数发生crash
- Java程序性能优化总结--------变量和函数调用篇
- 在C++ 程序中调用被 C 编译器编译后的函数,为什么要加 extern
- 编译原理之学习 lua 1.1 笔记 (二) 函数调用与局部变量
- C++程序运行时内存布局之----------局部变量,全局变量,静态变量,函数代码,new出来的变量
- 使用JNIEnv全局变量调用FindClass()等函数发生crash
- 编译原理扫描程序,判断当前输入的程序中程序调用的函数是那个函数原型
- 关于函数内部调用全局变量的问题
- Java 中的 int 与 Integer 用于 List<Integer> 时,以及通过打印变量检测程序运行和函数调用次数计数
- 在C++ 程序中调用被C 编译器编译后的函数,为什么要加extern “C”
- 在C++ 程序中调用被C 编译器编译后的函数,为什么要加extern “C”?
- 在C++ 程序中调用被 C编译器编译后的函数,为什么要加 extern “C”声明?
- AIX 下xlC编译可共用主程序全局变量的动态库