一个程序的产生和运行过程
2011-04-02 13:57
459 查看
这儿的程序主要是指windows下的窗口程序,其实其他的也是大同小异。
我们运行的客户端程序(需要连接服务器)或者windows程序(不需要连接服务器),一般而言都是我们看到界面,然而他是如何运行的,原理是什么,我们却不清楚。。。
我们就以汇编程序编译为例子吧。首先我们需要先在编辑器里面编写调试汇编代码。然后用汇编编译器编译源代码,结果就是.asm的源代码变成了.obj的文件。这其实是一个对象。这还不够。我们还需要一个资源文件,以.re为后缀名。然后用链接器将。obj文件和。re文件链接到一块,并且插入.inc文件里的代码,这样我们就得到了。exe文件,就是可执行文件。
这个文件其实是二进制的文件,要是我们有一双透视眼,可以看见软件的代码,里面应该全部是0.1.0.1,1.0.1。0的二进制代码,肯定是天书无疑,因为没有人懂得他是什么意思,除了处理器。其实我们可以查看的,不过我们不会看到0101,而是看到,123b,78d23e,之类的,这是十六进制。用win32asm就可以达到这种效果。这是因为变为十六进制比较节省空间,不然的话,光0101就显示不完了,更不要说反汇编代码了。。。。其实软件里还是二进制代码,0101.。。
其实很多地方都是用16进制代替二进制,只是代替而已,其实还是二进制,不是十六进制。。比如反汇编软件里,教科书里的可执行文件,内存,处理器的寄存器里。。。
运行此可执行文件,软件首先初始化,然后软件的二进制信息会载入内存,此后处理器与内存交互,处理器处理二进制信息并给出处理结果,处理结果存储到显卡的存储器,显卡处理后将结果显示给运行程序的客户。。。
但是处理器如何分别内存里的那些存储单元里存储的0101001,那些是程序指令,那些是数据呢?因为一个指令载入内存是二进制,一个数据载入内存也可以是同样的二进制。答案是处理器靠“段”来分辨。当一个程序的二进制代码载入内存时,会形成三个段:一个是代码段,存储指令,更确切的说是存储指令编译而来的二进制代码;一个是堆段,存储一般变量;另一个是堆栈段,这个堆栈是很常用的一个数据结构,不知道的请百度之,用于存储函数的参数。
处理器从指令指针所指的地方开始执行。以c语言为例,指令指针指向代码段中main()函数所在的内存单元,并开始一路向下执行。当遇到调用其他函数时,由于需要进入函数内部执行,需要保存当前指令指针所在的位置,以便执行完调用函数时,可以方便的回来继续执行。此时,处理器把程序指针所指的内存单元(想想是哪一个内存单元)位置的数据存入堆栈段,然后执行那个调用的函数,把函数的参数也压入堆栈之中,然后调用,等到压入参数调用完毕,函数也就执行完毕。那么此时此刻,堆栈中就剩一个指令指针的数据,处理器再把此数据所在的内存单元传给指令指针,告诉指令指针指向何处,继续执行指令。这样就完成了一个函数的调用。然后如此不断地执行程序指令,直到内存的代码段执行完毕。程序也就执行完毕。也就是我们关闭了或退出了应用程序。
我们只看到了软件运行以及给出结果,或者是你的电脑健康状况良好,qq已登录,hello酷狗之类,却不知我们的电脑做了那么多工作。。。不过这样也好,我们只需点一下,然后几十秒以后有反应,我们可以听音乐,我么可以看电影,可以杀毒,不是也很好吗?
我们运行的客户端程序(需要连接服务器)或者windows程序(不需要连接服务器),一般而言都是我们看到界面,然而他是如何运行的,原理是什么,我们却不清楚。。。
我们就以汇编程序编译为例子吧。首先我们需要先在编辑器里面编写调试汇编代码。然后用汇编编译器编译源代码,结果就是.asm的源代码变成了.obj的文件。这其实是一个对象。这还不够。我们还需要一个资源文件,以.re为后缀名。然后用链接器将。obj文件和。re文件链接到一块,并且插入.inc文件里的代码,这样我们就得到了。exe文件,就是可执行文件。
这个文件其实是二进制的文件,要是我们有一双透视眼,可以看见软件的代码,里面应该全部是0.1.0.1,1.0.1。0的二进制代码,肯定是天书无疑,因为没有人懂得他是什么意思,除了处理器。其实我们可以查看的,不过我们不会看到0101,而是看到,123b,78d23e,之类的,这是十六进制。用win32asm就可以达到这种效果。这是因为变为十六进制比较节省空间,不然的话,光0101就显示不完了,更不要说反汇编代码了。。。。其实软件里还是二进制代码,0101.。。
其实很多地方都是用16进制代替二进制,只是代替而已,其实还是二进制,不是十六进制。。比如反汇编软件里,教科书里的可执行文件,内存,处理器的寄存器里。。。
运行此可执行文件,软件首先初始化,然后软件的二进制信息会载入内存,此后处理器与内存交互,处理器处理二进制信息并给出处理结果,处理结果存储到显卡的存储器,显卡处理后将结果显示给运行程序的客户。。。
但是处理器如何分别内存里的那些存储单元里存储的0101001,那些是程序指令,那些是数据呢?因为一个指令载入内存是二进制,一个数据载入内存也可以是同样的二进制。答案是处理器靠“段”来分辨。当一个程序的二进制代码载入内存时,会形成三个段:一个是代码段,存储指令,更确切的说是存储指令编译而来的二进制代码;一个是堆段,存储一般变量;另一个是堆栈段,这个堆栈是很常用的一个数据结构,不知道的请百度之,用于存储函数的参数。
处理器从指令指针所指的地方开始执行。以c语言为例,指令指针指向代码段中main()函数所在的内存单元,并开始一路向下执行。当遇到调用其他函数时,由于需要进入函数内部执行,需要保存当前指令指针所在的位置,以便执行完调用函数时,可以方便的回来继续执行。此时,处理器把程序指针所指的内存单元(想想是哪一个内存单元)位置的数据存入堆栈段,然后执行那个调用的函数,把函数的参数也压入堆栈之中,然后调用,等到压入参数调用完毕,函数也就执行完毕。那么此时此刻,堆栈中就剩一个指令指针的数据,处理器再把此数据所在的内存单元传给指令指针,告诉指令指针指向何处,继续执行指令。这样就完成了一个函数的调用。然后如此不断地执行程序指令,直到内存的代码段执行完毕。程序也就执行完毕。也就是我们关闭了或退出了应用程序。
我们只看到了软件运行以及给出结果,或者是你的电脑健康状况良好,qq已登录,hello酷狗之类,却不知我们的电脑做了那么多工作。。。不过这样也好,我们只需点一下,然后几十秒以后有反应,我们可以听音乐,我么可以看电影,可以杀毒,不是也很好吗?
相关文章推荐
- 编写一个java程序,从1加到100,每做一次加法,就休眠1秒,当程序运行过程中,杀死这个程序。 再次运行,还能从上次的计算结果继续下去
- .NET程序运行过程产生的问题
- 1.3—一个典型的JAVA程序的编写和运行过程
- 单片机中一个程序的运行过程
- 程序执行过程的跟踪:(用debug来跟踪一个程序的运行过程) 整理总结
- 在ubuntu下创建、编译并运行一个C++程序的过程
- 举例说明一个 java程序的加载,初始化以及运行过程
- 一个完整的Java程序运行过程会涉及以下内存区域
- 编写一个java程序,从1加到100,结果是5050。 每做一次加法,就休眠1秒 当程序运行过程中,杀死这个程序。 再次运行,还能从上次的计算结果继续下去。
- java拾遗4----一个简单java程序的运行全过程
- java 运行一个程序的全部过程
- 一个简单程序的创建与运行过程
- [Java 09 多线程] 线程是指一个进程在执行过程中可以产生更小的程序单元
- [Java 09 多线程] 线程是指一个进程在执行过程中可以产生更小的程序单元
- (迟到的博客,始终是一个过程)Linux/Unix环境下计算C程序运行时间
- 一个简单java程序的运行全过程
- 菜鸟功略(怎样运行好一个HelloWorld程序)
- 【已解决】安装Scrapy过程中出错:ERROR: ‘xslt-config’ 不是内部或外部命令,也不是可运行的程序 或批处理文件。
- 当运行VS2008时,新建一个win32程序时,要进行相应的配置 , VS2005下配置OpenCV2.1.
- 由于另外一个程序或正在运行的服务可能正在使用网络地址转换组件