多年前的文章,说实话我自己都忘了内容是啥了,给想了解汇编语言或者想了解CPU工作过程的同学一点参考吧.受限于水平,错误再所难免,注意甄别.没有标准的答案,都是个人理解原创.喜欢就点赞收藏.
1.计算机语言
汇编语言它是计算机语言,计算机语言说通俗点就是人类与计算机(CPU)沟通的桥梁,计算机它不认识人类的语言,听不懂也读不懂,要让计算机替我们去完成我们的工作,就需要我们将要交给计算机完成的任务翻译为计算机语言。
2.汇编语言简介
汇编语言是各种语言中的一种,它属于低级的计算机语言,这是相对于面向过程的C/C++语言,以及面向对象的C++,java而言(个人理解C是纯过程/近底层,C++是个多面手既能过程也能对象/既底层又高层,Java是纯对象/偏高层)。它是除机器语言以外最接近硬件的计算机语言,而且可以通过学习汇编语言深入的了解操作系统的底层运行机制,并以CPU的角度思考问题。这样可以让你在编写高级语言的程序的时候避免很多错误,并且能更深入理解高级语言的执行原理。
因为汇编语言属于低级语言,所以既然低级就肯定不容易被普通用户认识,这需要一定的硬件基础知识和一些计算机工作原理的知识。以前在大学阶段学过汇编语言,但没有当回事儿。工作以后才发现这个语言是个好东西,它其实是个非常重要的基础课程。所以现在有时间就把书打开多看一点,学一点。
3.汇编语言分类
汇编语言目前常见的有两种:一个是基于8086/88架构的DOS下的16位汇编语言,还有就是基于80386架构及其以后型号的windows下32位汇编语言。我不知道linux下有没有汇编语言。顺便说一下,不管什么汇编语言它所编出来的程序都属于软件,所以不管什么软件都需要依赖操作系统这个基础平台,它才可以被硬件CPU所执行,因为操作系统就是提供硬件与用户之间的接口,所有软件都要通过它来分配到硬件资源(不知道对不对哈:)才可以被执行)。一般先学习16位的DOS汇编,然后再学32位的windows汇编。所以我们先谈谈16位的DOS汇编哈。
(新插入一段小故事关于C++: C++之父本贾尼.斯特劳斯斯特鲁普说他在贝尔实验室工作的时
候,那时C++还没诞生,他想构建一个分布式系统,于是他研究了当时的多种计算机语言,都无法
满足他的要求,就是既要支持高级特性又要能深入底层即性能要求还要高.他就想既然现有语言
无法满足他的要求他就索性创立一门语言.他就在C的基础上改进并扩充,于是诞生了C++.他没
说他后来他的分布式系统做好没,但C++却成了他的重要贡献,有趣的是他不是一开始就打算要
创立C++的,而是要构建分布式系统的副业.这真是无心插柳柳成荫.)
4.了解CPU基本结构(这里还是16位的CPU)
要学汇编语言首先就是要了解CPU,你只有了解了CPU才能了解汇编语言的执行,因为它基本就是直接在操作CPU的各个组成单元(像寄存器)。在维基百科上找了这个图,如下:
上面这个CPU的逻辑结构图是8088的,8088和8086大的架构差不多,所以就以这个为例介绍下各个组成部分的作用。
主寄存器:
AX(AH,AL)累加寄存器,一般用作暂存数据;
BX(BH,BL)基址寄存器,一般用作偏移地址存放;
CX(CH,CL)计数寄存器,一般用在循环控制次数;
DX(DH,DL)数据寄存器,好像和AX差不多吧;
SP堆栈指针寄存器,栈指针;
BP基址指针寄存器,可作SP使用;
SI源变址寄存器和DI目的变址寄存器,这两个做为BX扩展用于偏移地址存放。
段寄存器:
CS:代码段寄存器,任何一个程序都是从代码段开始执行的,CS寄存器指明了代码段的段地址。
DS:数据段寄存器,存放程序中数据部分的段地址。
SS:堆栈段寄存器,堆栈是内存中特殊的内存块,堆与栈不同,目前我只知道栈是尊循“先进 后出,后进先出”的原则而使用。
ES:附加段寄存器,应该是作为DS数据段寄存器的扩充吧。
地址加法器:
这是用在对内存寻址时所使用,它通过将段寄存器中的段地址与BX、SI、DI等寄存器中的偏移地址作一定处理从而输出物理地址,然后就可以访问内存单元了。汇编程序中的地址只是逻辑地址,并不是真实的内存上的地址。
在程序实际运行时每次访问内存都会先将逻辑地址转换成物理地址才可以访问到物理内存。关于CPU寻址,逻辑地址,物理地址我也会再写篇文章来讨论。
逻辑运算单元和控制单元:这是CPU最核心的单元,我们暂只记住它们是负责执行与控制就好了。
内部数据,地址总线:CPU内部各部件之间通信的通道。
外部地址总线:用来传输CPU想要读取/写入内存单元的物理地址。它的宽度就决定了CPU能够访问的内存的最大容量。
外部数据和控制总线:一个用来与内存传输数据一个用来传输控制信号。
5.了解CPU工作过程
CPU执行程序的过程分四个阶段:提取、解码、执行、写回。
简而言之,提取就是CPU从内存中获取指令,通过IP寄存器中的地址找到要执行的程序,当然具体是通过把IP寄存器中保存的地址从外部总线发送到内存中,然后内存从数据总线将指令或数据返回给CPU。
解码就是分析从内存中返回的是指令还是数据,因为同样是一串二进制代码,可以是数据也可以是指令,如果是指令是做什么操作(根据CPU自身的指令集架构来把二进制的数据解析为指令或数据),然后进入执行阶段。执行当然就是算术逻辑单元的事情了,它负责将指令执行完毕。最后是写回,CPU通过外部数据总线又将数据写回到内存中。
以上的过程呢,是说得很简单的,实际上要复杂些,不过这里只是稍微的提一下。
6.简单汇编语言指令
了解了CPU执行指令的过程后,再看一下简单的指令,就看看加法操作的指令吧:
mov ax 1
add ax 1
上面的mov,add叫做操作码,它就指明了要让CPU做什么操作,这里的mov表示“传送”,add表示“加法运算”;
ax呢是一个CPU内部的寄存器,全名叫通用寄存器,它一般就用来暂时储存一些数据。
所以上面的两行指令执行过程就是:先将数据1传送到寄存器ax中,然后执行ax=ax+1,这样最终ax里就保存了执行结果2。
还是很简单吧,当然这是最简单的操作了,而且上面的指令不是完整的汇编语言的格式。一个完整的汇编语言程序还需要添加很多的伪指令(是属于让编译器执行解释的代码),说明等等。
以上所有只是汇编以及了解汇编所需要的知识的一部分,是泛泛而谈。里面很多地方的一个小知识点如果要详细写出来的话都可以写一大篇出来。
总结: 文章写了多年了,虽然如今CPU的硬件架构64位已成主流,但基本原理应该是一样的.从事软件工作对硬件有了解很有必要.