汇编语言简介
汇编语言是一门直接与硬件相关的编程语言,它是一台机器的机器语言的符号语言。每一台计算机都有自己的指令系统,不一样的机器由于硬件的差异,采用的指令系统不一样,而汇编,也是每台机器都不太一样的,因为汇编就是用符合去代替指令中的操作码以及操作数。可以这样说,理解计算机CPU在某一架构(物理实现)下的工作原理,是学好汇编很重要的一点。
汇编语言的出现大大提高了编程效率,但是有一个问题就是不同CPU的指令集可能不同,这样就需要为不同的CPU编写不同的汇编程序。于是又出现了高级语言比如C,或者是后来的C++,Java,C#。 高级语言把多条汇编指令合成成为了一个表达式,并且去除了许多操作细节(比如堆栈操作,寄存器操作),而是以一种更直观的方式来编写程序,而面向对象的语言的出现使得程序编写更加符合我们的思维方式。我们不必把尽力放到低层的细节上,而更多的关注程序的本身的逻辑的实现。对于高级语言来说需要一个编译器来完成高级语言到汇编语言的转换。所以对比不同的CPU结构,只需要有不同编译器和汇编器就能使得我们的程序在不同CPU上都能运行了。对于目前来说,一般出现了新的指令,会有对应的新的汇编器和编译器。所以编译器可以把一些高级语言的表达式编译成新的汇编指令,这样对于高级来说不会有任何变化; 当然还有一种情况就是高级语言会增加新的语法来对应一些新的汇编语言和指令。但是这种情况出现的几率很小。所以如果编译器不支持新的指令,那么只有只用汇编会来实现了。
另外要说的一点是,对于C#和Java这种运行在虚拟机上的语言,编译过程有所不同。 对于C,C++的程序,生成的可执行文件,可以在兼容的计算机上直接运行。但是C#和JAVA这些语言则不同。他们编译过程是相似的,但是他们最终生成的并不是机器码,而是中间代码,对于C#而言叫IL代码,对于JAVA是字节码。所以C#,JAVA编译出来的文件并不能被执行。我们在使用.NET或JAVA时都需要安装.NET CLR或者JAVA虚拟机,以.NET为例,CLR实际是一个COM组件,当你点击一个.NET的EXE文件时,它和C++等不一样,不能直接被执行,而是有一个垫片程序来启动一个进程,并且初始化CLR组件。当CLR运行后,一个叫做JIT的编译器会吧EXE中的IL代码编译成对应平台的机器码,然后如同其他C++程序一样被执行。
CPU简介
寄存器
首先寄存器是CPU里面的重要的部件,简单来说,就是个存储部件,速度很快,造价高,所以只有这类硬件在计算机里比较少。寄存器是CPU里面很重要的一个部件,通常在CPU里面都有一个寄存器组,里面放着有通用寄存器,专用寄存器等(因CPU而异)。
这个是80x86处理器架构下的寄存器。
这个是支持64位的cpu里的寄存器。
后来的pentium4及更高型号处理器增加了8个通用寄存器实现更多功能
寻址方式
我们知道,寄存器里面一开始是没有东西的,由CPU的控制器决定让CPU去哪里去数据,进行什么操作。既然要取数据,就会涉及寻址。所谓寻址,就是CPU要去内存的哪个地址去取数据。在80x86下,一般有
在这里简单说一下实现寻址,主要是通过段寄存器CS,DS,SS,ES()来实现,一般由这些CS,DS,SS来指向起始位置,然后由其他指针寄存器去实现代码数据的移动变换(我的理解就是内存的寻址)。举例子,比如CS来说,一般CS指向正在执行的代码段的开始位置,然后会有搭档IP(指令指针)去实现指向要执行的下一条指令。然后是SS指针,SS存放堆栈段栈底,然后SP指向栈顶(入栈出栈SP自加自减),再搭配BP指针(读取任意内存位置的堆栈数据)。
利用寄存器可以实现CPU内部的寻址机制,我们就可以利用汇编找到操作数了。
CPU指令集
每个CPU都有自己的指令集合,汇编就是这些指令的符号表示。
一条指令往往是由操作码和操作数组成。利用寄存器和寻址机制,我们搞定了操作数。那么操作码呢?
在汇编语言里,也有自己的语法:
然后汇编语言的更多相关细节就不展开详细说了,像调用系统中断,BIOS中断,以及DOS中断等。(中断程序就是写好了的一个函数,中断向量表存放着这个函数的入口地址)
总之汇编就是把我们计算机里面的机器操作指令转换为了便于记忆的符号标识。学习汇编可以让我们更清楚得理解程序是怎么在CPU内部运行的。
然后通过一段简单的汇编代码体会一下汇编是如何利用寄存器和寻址机制进行工作的。
|