2019.11.29 星期五 阴
程序编译成可执行文件的过程:程序编译的四个阶段:
1.预处理阶段(.c—.i)
2.编译(.i—.s)转换为汇编语言文件
3.汇编阶段(.s—.o)得到机器语言
4.链接阶段
源代码>编译器(生成Obj格式)>链接(link)>可执行文件;
- 编译:编译就是把高级语言变成计算机可以识别的2进制语言,计算机只认识1和0,编译程序把人们熟悉的语言换成2进制的。
- 词法分析:词法分析的任务是对由字符组成的单词进行处理,从左至右逐个字符地对源程序进行扫描,产生一个个的单词符号,把作为字符串的源程序改造成为单词符号串的中间程序。执行词法分析的程序称为词法分析程序或扫描器。
- 语法分析:编译程序的语法分析器以单词符号作为输入,分析单词符号串是否形成符合语法规则的语法单位,如表达式、赋值、循环等,最后看是否构成一个符合要求的程序,按该语言使用的语法规则分析检查每条语句是否有正确的逻辑结构,程序是最终的一个语法单位。编译程序的语法规则可用上下文无关文法来刻画;
- 语义检查中间代码生成:中间代码是源程序的一种内部表示,或称中间语言。中间代码的作用是可使编译程序的结构在逻辑上更为简单明确,特别是可使目标代码的优化比较容易实现中间代码,即为中间语言程序,中间语言的复杂性介于源程序语言和机器语言之间;
- 代码优化:代码优化是指对程序进行多种等价变换,使得从变换后的程序出发,能生成更有效的目标代码。所谓等价,是指不改变程序的运行结果。所谓有效,主要指目标代码运行时间较短,以及占用的存储空间较小。这种变换称为优化;
- 目标代码生成:目标代码生成是编译的最后一个阶段。目标代码生成器把语法分析后或优化后的中间代码变换成目标代码;
-
[链接(link)[:把头文件中引用到的函数链接并入到可执行文件的过程;
列如:printf函数存在于一个名为printf.o的单独预编译目标文件中。必须得将其并入到hello.o的程序中,链接器就是负责处理这两个的并入,结果得到hello文件,它就是一个可执行的目标文件。 - [汇编代码[:
- 赋值语句:
- 跳转语句:
- 计算语句:
汇编指令和机器码一一对应;汇编≈机器码。
编译器在编译的时候,Debug(调试版本)和Release(发行版本)编译出来的汇编码是不一样的;
- Debug:模式下会对所有代码进行编译,还会增加调试代码,方便调试;
- Release:模式下编译器会对代码进行优化,没有调试代码,减小程序体积,加快执行速度;
-所以调试的时候建议使用Debug,因为它会对每句代码生成对应的汇编;
- 寄存器:
- EAX:累加(accumulator)寄存器:是很多加法乘法指令的缺省寄存器。
- EBX:"基地址"(base)寄存器:在内存寻址时存放基地址。
- ECX:计数器(counter):是重复(REP)前缀指令和LOOP指令的内定计数器。
- EDX:总是被用来放整数除法产生的余数。
- ESI:源索引寄存器:在很多字符串操作指令中, DS:ESI指向源串。
- EDI:目标索引寄存器:ES:EDI指向目标串。
- EIP:程序计数器:存放下一个CPU指令存放的内存地址,当CPU执行完当前的指令后,从EIP寄存器中读取下一条指令的内存地址,然后继续执行
- ESP:栈顶寄存器:存放当前线程的栈顶指针。
- EBP:栈底寄存器:存放当前线程的栈底指针。
-
EFL:标志寄存器
PUSH:压栈
POP:出栈
- 一个由C/C++编译的程序占用的内存分为以下几个部分:
- 栈区(stack):由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
- 堆区(heap) :一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。注意它与数据结构中的堆是两回事,分别方式倒是类似于链表。
- 全局区(静态区)(static):全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后由系统释放;
- 文字常量区 :常量字符串就是放在这里的。 程序结束后由系统释放;
- 程序代码区 :存放函数体的二进制代码;