CPU是计算机的中央处理器,负责执行组成计算机程序的指令。为此,CPU必须能够解释机器码即计算机程序的最低级别表示形式,以让CPU可以直接执行。机器码是一系列的二进制指令,每个指令都代表CPU可以执行的特定操作。指令由一系列1和0组成,CPU能够直接读取和执行这些指令是因为它的硬件设计用于解释这种特定格式的编码(不同位的1/0代表的不同含义)。
编译过程可以分为四个阶段:
预处理(-E)
预处理就是对源程序中的伪指令(以#开头的指令)和特殊符号进行处理的过程。伪指令包含宏定义指令,条件编译指令和头文件包含指令。gcc对C源文件进行预处理后会输出 .i 文件。
主要处理规则如下:
(1)将所有#define删除,并且展开所有的宏定义。
(2)处理所有条件编译指令。如#if、#ifdef等
(3)处理#include预编译指令,将被包含的文件插入该预编译指令的位置。
(4)删除所有的注释
(5)添加行号和文件标识,以便于编译时编译器产生调试用的行号信息及编译时产生编译错误或警告时能够显示行号信息
(6)保留所有的#pragma编译器指令,因为编译器需要使用它们。
编译(-S)
编译就是把预处理完的文件进行一系列词法分析、语法分析、语义分析及优化后生成相应的汇编代码。使用gcc进行编译时,默认情况下,不输出该文件,生成的汇编文件是 .s 文件
汇编(-c)
汇编就是将汇编代码转变为机器可以执行的二进制代码,每一个汇编语句几乎都对应一条机器指令。汇编相对于编译过程比较简单,根据汇编指令和机器指令的对照表一一翻译即可。
汇编:用一个字符来代替机器码
汇编语言和机器码不可移植
高级语言c语言可以移植,C语言可以做到不区分处理器的架构,主要是依赖编译器。
指令:
能够直接指示处理器执行某种运算的命令称为指令(如加、减、乘 ...) ;指令在内存中以机器码(二进制)的方式存在
能够编译生成一条32bit大小的机器码,并且能被CPU执行;
每一条指令都对应一条汇编
程序是指令的有序集合
链接
在成功汇编之后,就进入链接阶段。链接主要是为了解决多个文件之间符号引用的问题。编译时编译器只对单个文件进行处理,如果该文件里面需要引用到其他文件中的符号,那么这时在这个文件中该符号的地址是没法确定的,只能等链接器把所有的目标文件链接到一起,才能确定最终的地址,最终生成可执行文件。
.c文件-------gcc------X86系统
.c文件-------ARM-gcc------ARM处理器
汇编语言最后.end一行需要加回车
@汇编的中符号
1.指令:能够编译生成一条32bit机器码,并且能被CPU识别和执行
2.伪指令:本身不是指令编译器可以将其替换成若干条指令(例乘法转换成连加)
3.伪操作:不会生成指令,只是在编译阶段告诉编译器怎么编译
汇编中符号中的ARM指令集分为:
1.数据处理指令:进行数学运算、逻辑运算
2.跳转指令:实现程序的跳转,本质就是修改了PC寄存器
3.Load/Srore指令:访问 (读写)内存
4.状态寄存器传送指令: 用于访问(读写) CPSR寄存器触发软中断(改变寄存器的状态)
5.软中断指令: 触发软中断
6.协处理器指令:操作协处理器的指令(例ARM无法编译float类型,需外连一个协处理器)
简述C语言和汇编语言的本质区别是什么
1、因为汇编语言实质上是机器语言的助记符,是直接面对CPU的语言,所以汇编语言的运行效率比C语言高;
2、汇编语言对硬件的可操控性强,C语言硬件可操控性比较差;
3、汇编语言的目标代码体积小,C语言目标代码体积大;
4、汇编语言不易维护,C语言容易维护;
5、汇编语言可移植性很差,C语言可移植性很好;
6、汇编语言比C语言难学,因为汇编语言所需要的编程知识很多也很复杂。