首页 计算机理论基础

计算机理论基础

举报
开通vip

计算机理论基础计算机理论基础 1.1计算机中的编码 1.1.1(数字编码 由于二进制有很多优点,所以计算机中的数用二进制表示,但人们与计算机打交道时仍然习惯于用十进制,在输入时计算机自动将十进制转换为二进制,而在输出时将二进制转换为十进制。为便于机器识别与转换,计算机中的十进制数的每一位用二进制编码表示,这就是所谓的十进制数的二进制编码,简称二—十进制编码(BCD)。 二—十进制编码的方法很多,最常用的是8421 BCD码。8421 BCD码有十个不同的数字符号,逢十进位,每位BCD码用四位二进制表示。例如: 83.1...

计算机理论基础
计算机理论基础 1.1计算机中的编码 1.1.1(数字编码 由于二进制有很多优点,所以计算机中的数用二进制表示,但人们与计算机打交道时仍然习惯于用十进制,在输入时计算机自动将十进制转换为二进制,而在输出时将二进制转换为十进制。为便于机器识别与转换,计算机中的十进制数的每一位用二进制编码表示,这就是所谓的十进制数的二进制编码,简称二—十进制编码(BCD)。 二—十进制编码的方法很多,最常用的是8421 BCD码。8421 BCD码有十个不同的数字符号,逢十进位,每位BCD码用四位二进制表示。例如: 83.123对应8421 BCD码是 1000 0011. 0001 0010 0011 同理,111 1001 0010. 0010 0101 BCD码对应的十进制数十792.25。 1.1.2(字符编码 字母、数字、符号等各种字符也必须按照特定的规则用二进制编码才能在计算机中表示。字符编码的方式很多,世界上最普遍采用的一种字符编码是ASII码(美国信息交换标准码)。 ASCII码用7位二进制编码,它有128种组合,可以表示128种字符。包括0~9,十个阿拉伯数字字符,大、小写英文字母(72个),常用标点符号和各种控制字符,参见附录1。在计算机中用一个字节表示一个ASCII码字符,最高位置为0。例如,00110000~00111001(即30H~39H)是数字0~9的ASCII码,而01000001~01011010(即41H~5AH)是大写英文字母A~Z的ASCII码。详见ASCII字符表。 1.1.3(汉字编码 用计算机处理汉字,每个汉字必须用代码表示。键盘输入汉字是输入汉字的外部码。外部码必须转换为内部码才能在计算机内进行存储和处理。为了将汉字以点阵的形式输出,还要将内部码转换为字型码。不同的汉字处理系统之间交换信息采用交换码。 (1)外部码 汉字主要是从键盘输入,每个汉字对应一个外部码,外部码是计算机输入汉字的代码,是代表某一个汉字的一组键盘符号。外部码也叫输入码。汉字的输入方式不同,同一个汉字的外部码可能不一样。目前已有数百种汉字外部码的编码 方案 气瓶 现场处置方案 .pdf气瓶 现场处置方案 .doc见习基地管理方案.doc关于群访事件的化解方案建筑工地扬尘治理专项方案下载 ,大致可以归纳为四种类型:数字吗、音码、形码和音形码。数字吗是将汉字按照某种规律排序,然后赋予它们数字编号,这个数字编号就作为汉字的编码。常见的数字码,如区位码等, 这种编码方式无重码,可以找到其他编码方式难于找到的汉字,但难于记忆,要有手册备查。音码是以汉语拼音作为汉字的编码,只要学过汉语拼音,一般不需要经过专门训练就可以掌握,但是,用拼音方法输入汉字同音字很多,需要选字,影像输入速度,不知道读音的汉字也无法输入。形码是一个汉字拆成若干偏旁、部首、字根,或者拆成若干笔画,使偏旁、部首、字根或笔画与键盘对应编码,按字型敲键输入汉字。形码输入汉字重码率低、速度快,只要能看到的字行就可以拆分输入,但必须要经过专门训练,并且需要记忆大量的编码规律和汉字拆分原则。最常见的形码方案有五笔字型码等。音形码是拼音和字型相结合的一种 汉字编码方案,如自然码、钱码等。 (2)内部码 汉字内部码也称汉字内码或汉字机内码。在不同的汉字输入方案中,统一汉字的外部码不同。但同一汉字的内部码是惟一的。内部码通常使用其在汉字字库中的物理位置标示,可以用汉字在汉字字库中的符号或者用汉字在汉字字库的存储位置标示。汉字在计算机中至少要用两个字节表示(有用三字节、四字节表示的),在微型计算机中常用的是两字节汉字内码两字节汉字内码,就是汉字的国标码(用两个7位编码)的两个字节的最高位都改为“1”形成的。例如汉字“啊”,国标码为0110000,01000001,即30H,21H;内部码为10110000,10100001,即B0H,A1H。在计算机中通常处理的是以ASCII码表示的字符,一个字符在机器内以一个字节的二进制编码表示。实际上ASCII码只需7位,故在计算机内的字符编码的最高位是“0”。由此可见,以字节的最高位是0还是1。很容易区分是ASCII字符还是汉字。 (3)交换码 计算机之间或计算机与终端之间交换信息的时,要求其间传送的汉字代码信息要完全一致。为此,国家根据汉字的常用程度定出了一级和二级汉字字符集,并规定了编码,这就是国标GB2312-80《信息交换用汉字编码字符集基本集》,GB2312-80中的汉字的编码即国标码。该标准编码字符集共收录汉字和图形符号7445个,其中包括: ? 一般符号202个,包括间隙符、标点、运算符、单位符号和制表符等。 ? 符号60个,包括1. ~20.(20个),(1)~(20)(20个),?~?(10个)和(一)~(十)(10个)。 ? 数字22个,包括0~9和?~?。 ? 英文字母52个,大、小写各26个。 ? 日文假名169个,其中平假名83个,片假名86个。 ? 希腊字母48个,其中大、小写各24个。 ? 俄文字母66个,其中大、小写各33个。 ? 汉字拼音符号26个。 ? 汉字注音字母37个。 ? 汉字6763个。这些汉字分为两级,第一级汉字3755个,第二级汉字3008个。 这个字符集中的任何一个图形、符号及汉字都是用两个7位的字节表示(在计算机中当然用两个8位字节,每个字节的最高位为1来表示)。其中汉字占6763个。第一级汉字3755个,按汉语拼音字母顺序排列,同音字以笔画顺序为序;第二级汉字3008个,按照部首顺序排列。GB2312-80中,7445个字符和汉字分布在87个区中,每区最多94个字符。分布情况如下: 1~9区图形字符 10~15区空间未用 16~55区一级汉字 56~87区二级汉字 在GB2312-80标准中,对每个图形字符或汉字给出了两种汉子代码。一种是用两个字节二进制数给出的国标码(即内部码中所用到的);另一种是四位十进制区位码,其中高2位是某种字符或者汉字所在的区号,低2位是在区中的位置号。例如“啊”字的国标码是3021H,区位码是1601H。 (4)输出码 汉字输出码又称汉字字型码或汉字发生器的编码。众所周知,汉字无论字形有多少变化,也无论笔划有多有少,都可以写在一个方块中;一个方块可以看做m行n列的矩阵,称为点阵。一个m行n列的点阵共有m×n个点。例如16×16点阵的汉字,共有256个点。每个点可以是黑点或者非黑点,凡是笔划经过的点用黑点,于是利用点阵描绘出了汉字字形,汉字的点阵字形在计算机中称为字模。 在计算中用一组二进制数字表示点阵,用二进制数1表示点阵中的黑点,用二进制数0表示点阵中的非黑点。一个16×16点阵的汉字可以用16×16=256位的二进制数来表示,这种用二进制数来表示汉字点阵的方法称为点阵的数字化。汉字字形经过点阵的数字化后转换成一串数字,称为汉字的输出码。 同一汉字的输出码,即字型码,因选择点阵 的不同而不同。一个字节包含8和二进位, 所以16×16点阵汉字需要2×16=32个字节 表示;24×24点阵汉字需要3×24=72个字 节表示;32×32点阵汉字需要4×32=128 个字节表示。点阵的行列数越多,所描绘的 汉字越精细,但占用的存储空间越多。16× 16点阵基本能表示GB2312-80中的所有简 体汉字。24×24点阵则能表示宋体、楷体、 黑体等多字体的汉字。这两种点阵是比较常图1-8 汉字“中”的16×16点阵字 模 见的点阵,前一种一般用于显示,而后一种一般用于打印。除此之外,还有32×32、40×40、48×48、64×64、48×72、96×96和108×108等点阵,这些主要用于印刷。 1.2 计算机基础 1.2.1.计算机的发展 自1946年世界上第一台电子计算机问世以来,计算机技术得到了突飞猛记得发展。短短40多年的时间,已经历了四代的更替:电子计算机、晶体管计算机、集成电路计算机和大规模、超大规模集成电路计算机。20世纪80年代初日本和美国又分别宣布了第五代“非冯?诺依曼”计算机和第六代“神经”计算机的研制 计划 项目进度计划表范例计划下载计划下载计划下载课程教学计划下载 。 计算机按其性能、价格和体积的不同,一般分为5大类:巨型机、大型机、中型机、小型机和微型计算机。 微型计算机是20世纪70年代初研制成功的。一方面由于军事、空间及自动化技术的发展需要体积小、功耗低、可靠性高的计算机,另一方面,大规模集成电路技术的不断发展也为微型计算机的产生打下了坚实的物质基础。 微处理器是微型计算机的核心芯片,通常简称为μP或MP(MicroProcessor),它是将计算机中的运算器和控制器集成在一片硅片上制成的集成电路。这样的芯片也被称为中央处理单元,简称为CPU(Central Processing Unit)。 微型计算机简称为μC或MC(Micro Computer),它是有微处理器、适量内存和I/O接口电路组成的计算机。 30多年来,微处理器和微型计算机获得了极快的发展,几乎每两年微处理器的集成度翻一番,每2~4年更新换代一次,现已进入第六代。 1. 第一代(1971—1973年)4位或低档8位微处理器 1971年美国Intel公司研制成功的4004是集成度为2000个晶体管、片的4位微处理。1972年Intel公司推出低档8位的8008也属于第一代微处理器产品。 第一代微处理器的指令系统比较简单,运算能力差、速度慢(基本指令的执行时间为10~20μs),但价格低廉。软件主要使用机器语言及简单的汇编语言。 2. 第二代(1974—1978年)中高档8位微处理器 微处理器问世后,众多公司纷纷研制微处理器,逐步形成以Intel公司、Motorola公司、Zilog公司产品为代表的三大系列微处理器。1973年到1975年,中档微处理器以Intel 8080、Motorola的MC6800为代表。1976年到1978年,出现高档8位微处理器,典型产品位Intel 8085、Z80和MC6809。 第二代微处理器比第一代有了较多改进,集成度提高1~4倍,运算速度提高10~15倍,指令系统相对比较完善,已具有典型的计算机体系结构以及中断、存储器直接存取(DMA)功能。软件除汇编语言外,还可以使用BASIC、FORTRAN以及PL/M等高级语言。后期开始配上操作系统,如CP/M(Control Program Monitor)操纵系统,他运用于以8080A/8085A、Z80、MC6502为CPU,带有磁盘及各种外设的微型计算机系统。 3..第三代(1978—1981年)16位微处理器 1977年左右,超大规模集成电路工艺研制成功,一片硅片上可集成一万个以上的晶体管,16Kb和64Kb半导体存储器也已出现。微处理器及微型计算机从第二代发展到第三代。三大公司陆续推出16位微处理器芯片,如Intel 8086的集成度为29000晶体管/片,Z8000为17500晶体管/片,MC68000为68000晶体管/片。这些微处理器的基本指令执行时间约为0.15μs。以各项性能指标看,比第二代微处理器提高了很多,已达到或超过原来中、低档小型机的水平。用这些芯片组成的微型计算机有丰富的指令系统、多级中断系统、多处理机系统、段式存储器管理以及硬件乘除运算等。除此以外,还配备了功能较强的系统软件。为方便原8位机用户,Intel公司很快推出8088,其指令系统完全与8086兼容,内部结构仍为16位,但外部数据总线是8位。并以8088为CPU组成了IBM PC PC/XT等16位机。由于其性能价格比高,很快占领了世界市场。与此同时,Intel公司在8086基础上研制出性能更优越的16位微处理器芯片80286,以80286为CPU组成IBM PC/AT高档16位机。 以上介绍的是16位微型计算机发展的一条途径,即在原8位机的基础上发展而来。另一条途径是将已流行的16位小型计算机微型化,例如美国DEC公司将PDP-11/20微型化为LS-11,将中档PDP-11/34微型化为LSI-23,又如NOVA机微型化为MicroNOVA等等。 4.第四代(1985年后)32位高档位处理器 1985年,Intel公司退出了32位微处理器芯片80386。80386有两种结构:80386SX和80386DX。这两种的关系类似于8088和8086的关系。80386SX内部结构为32位,外部数据总线为16位,采用80287作协处理器,指令系统与80286兼容。80386DX内部结构、外部数据总线皆为32位,采用80387作为协处理器。 1990年,Intel公司在80386基础上研制出新一代32位微处理器芯片80486。它 310相当于把80386/80387及8KB(2×2Byte)高速缓冲存储器集成在一块芯片上,性能比80386大大提高。 5.第五代(1993年后)64位高档微处理器 1993年3月,Intel公司推出64位微处理器芯片Pentium(80586,P5),它的外 32部数据总线为64位,地址总线为32位,内存寻址空间为2B=4GB,工作频率为66MHz,以它为CPU的Pentium机是一种64位高档微机。IBM、Apple和Motorola三公司合作生产的Power PC芯片是又一种优异的64位微处理器芯片,以它为CPU的微型计算机型号为Macintosh。 6.第六代(1995年后)64位高档微处理器 1995年,Intel公司推出第六代微处理器PentiumPro(P6)。它采用了0.6μm工 36艺,集成了550万只晶体管。它有数据线64位,地址线36位,寻找范围为2B=64GB。 ?、Pentium工作频率达200MHz。随后,Intel公司陆续推出了P6的系列产品:Pentium?、Pentium?等。这些产品采用了多项先进技术,如:RISC技术,超级流水线技术、超标量结构技术(每个时钟周期可启动并执行多条指令)、MMX技术、动态分支预测技术、超顺序执行技术、双独立总线DIB技术;一级高速缓冲存储器(L1)采用双cache结构(独立的指令cache和数据cache)、二级高速缓冲处理器(L2)达256KB或512KB;支持多微处理器。 第六代微处理器性能优异,适应当前多媒体、网络、通信等多方面的要求。随着科学技术的发展,将会不断的对微处理器提出新的要求,新型、新概念的微处理器定会层出不穷。 1.2.2 计算机的分类 微处理器(MP-MICRO PROCESSOR)是集成在一片大规模集成电路芯片上的中央处理器,又称MPU,简称MP。它具有一般CPU的功能,它的体积远远小于一般CPU,还具有功耗低,价和可靠性高的优点。 按MPU处理数据的位数来看,微处理器可分为4位,8位,16位和32位MPU。32位微处理器是当今较先进最流行的微处理器,它所构成的微型计算机也是当今世界最流行的较先进的微型计算机。 从制造微处理器器件的工艺来看,可分为MOS工艺的通用微处理器和双极性TTL工艺的位片时微处理器,后者具有速度快、灵活多变但功耗较大的特点。位片时微处理器以位为单位构成MPU芯片,常用多片位片式微处理器构成高速、分布式系统和阵列式系统等,可以按实际需要,选择构成不同数位的微处理器,因而是个灵活多变。 1.3 1.3.1 硬件组成 一、微计算机系统的一般结构 微计算机系统和一般电子计算机结构上的共同之处在于:他们都是由硬件和软件两个大部分组成,可归纳为如下页所示的关系图。 二、硬件 微计算机硬件是机器的实体部分,其组成主机的各个部分—µP、RAM、ROM和I/O接口电路将在后面各章讲述,并从系统设计和连接的原则、方法出发,将之接入系统。 三、软件 微计算机的软件,从广义角度来说包括各种程序设计语言、系统软件、应用软件和数据库等。微计算机根据使用场合的不同和利用形态不同,因而设计者或生产厂家给它配上的软件规模也不同。 (一) 程序设计语言 程序设计语言是指用来编写程序的语言,是人和计算机之间用来交换信息所用的一种工具,又称编程环境,通常分为机器语言、汇编语言和高级语言三类。 1. 机器语言 机器语言就是能够直接被计算机识别和执行的语言。计算机中传送的信息是一种用“0”和“1”表示的二进制码,因此,机器语言程序就是用二进制代码编写的代码程序。对于每种微计算机,若使用的µP不同(因每种µP都有自己的指令系统),所以使用的机器语言也就不相同。显然,用计算机语言编写程序,优点是计算机认得,缺点是:直观性差、繁琐、容易出错,对不同的µP的机器也没有通用性能等,因而难于交流,在实际应用中很不方便,则很少直接采用。 (图) 2.汇编语言 基于机器语言的缺点,人们想出一种办法—用一种能够帮助记忆的符号,即用英文字母或缩写符号来表示机器指令,则称这种用助记符(Mnemonic)表示的机器语言为汇编语言。由于汇编语言程序使用这种帮助记忆的符号指令汇集而成的,因此程序比较直观,从而易记忆、易检查、便于交流。但是用助记符指令编写的汇编语言程序(又称源程序)计算机是不认得的;汇编语言源程序必须要翻译成与之对应的机器语言程序(又称目标程序)后,计算机才能执行。担任翻译加工的系统软件称为汇编程序(Assembler)。没有汇编程序的机器,对源程序的翻译可由人工来进行,这种翻译称为“手编”或人工代真,也可再用相同的µP的配有汇编程序的另外机器上去翻译成目标程序后,再送回本计算机执行。 由于汇编语言的符号指令与机器代码是一一对一应的,从执行的时间和占用的存储空间来看,它和机器语言一样是高效率的,同时也是计算机所用的µP不同而异。机器语言和汇编语言都是面向机器的程序设计语言,又称初级语言。使用它便于利用计算机的所有硬件特性,是能直接控制硬件的一种语言。 3.高级语言 又称为算法语言。为了从根本上克服初级语言的缺点,一方面为了使程序设计语言适合于描述各种算法,使程序设计中所用语句与实际问题更接近;另一方面也为了使程序设计可以脱离具体的计算机结构,不必了解其指令系统,这就出现了各种高级语言。用高级语言编写的程序通用性更强。BASIC,FORTRAN,Pascal,COBOL和C都是常用的高级语言。 高级语言程序计算机也不认得,用高级语言编写的源程序仍需翻译成机器语言表示的目标程序,计算机才能执行,这就需要各种解释程序或编译程序。其过程在算法语言课程中已有介绍,本课程不再赘述。 综上所述,汇编语言和高级语言各有所长。用高级语言虽然可以大大减少程序编制的时间,但却得不到最有效的目标程序。与由高级语言源程序编译产生的目标程序相比较,熟练的程序员用汇编语言源程序翻译得到的机器代码,一般能节省储存空间,执行速度更快,在要求高效率、储存容量有限的应用中是常采用的一种语言。汇编语言离不开CPU指令系统,通过它有助于了解微型计算机工作原理。本课程以汇编语言为主,阐明编程原理和方法。 (二)系统软件 仅有硬件的裸机,自然不能发挥计算机的作用,就是你选用了最合适的语言也无法使计算机运转。为此,还必须有系统软件。系统软件是由机器的设计者提供给用户的,是指为了方便用户和充分发挥计算机效能的一系列程序。人就是通过这些程序来使用机器的。系统软件是各种应用程序的支持软件,包括监控程序、操作系统、汇编程序、解释程序、编译程序、诊断程序等。 1. 监控程序 又称管理程序。在单板微计算机上常配有1,2K字节的监控程序,通常固化在内存ROM中,又称“驻留”(Residend)软件。其主要功能是:对主机和外部设备的操作进行合理的安排,接受分析各种命令,实现人机联系。在它的支持下,可以在RAM中存放机器语言程序代码和数据代码,或者对它们进行修改,从任何要求的程序点上执行机器语言程序,由存储器送出计算结果等调试工作。通常在监控程序中还包括一些可供用户条用的有用子程序。如TP801单板机的监控程序叫做TPBUG。 2. 操作系统(O.S) 操作系统是在程序管理基础上,进一步扩充许多控制程序所组成的大型程序系统。其主要功能有:合理地组织整个计算机的工作流程,管理和调度各种软、硬件资源—包括CPU、存储器、I/O设备和软件,检查程序和机器的故障。用户通过操作系统便可方便的使用计算机。操作系统是计算机系统的指挥调度中心。从广义来讲,操作系统应包括引导程序、监控程序、输入/输出驱动程序、连接程序、编辑程序、汇编程序、解释程序、编译程序、数据库等,是各种语言程序的运行环境。 操作系统具有层次结构,我们可以把操作系统管理的资源表示为图1-4所示的层次。 有了操作系统的微计算机系统的所有资源都将有操作系统统一管理起来,用户并不必过问各个部分资源的分配使用情况,而只是通过使用它的一些命令就行了。例如:通过使用它的实用程序命令就可调用各种语言。因此,可以说操作系统是用户和裸机间的接口。 微计算机系统常用的操作系统有以下几种: (1) CP/M(Control Program /Monitor)它是较早的微机操作系统,是一种单用 户单道程序的小型操作系统,它允许用户通过控制台或键盘对系统进行控 制和管理,它仅有磁盘文件管理系统。 (2) MS-DOS(Microsoft-Disk Operating System)是美国Microsoft公司开 发的通用16位单用户磁盘操作系统,主要包括文件管理和外设管理的操 作系统。该系统吸收了CP/M及其他操作系统的长处,结构优良,软件上 的互换性强,是IBM-PC机的主要操作系统。 (3) UNIX是Bell实验室提供的一种分时操作系统,是16位为计算机的标准 操作系统。 操作系统通常放在软磁盘或硬磁盘中,容量为十几K,几十K字节。 3. 汇编程序 汇编程序的功能是把用汇编语言编写的源程序翻译成机器语言表示的目标程序。汇编语言可存放在内存的ROM中,称为驻留的汇编程序。具有驻留程序的微计算机可直接把汇编语言源程序翻译成机器语言的目标程序;汇编语言也可存放在磁盘上,使用这种汇编程序时,应在操作系统支持下,先把汇编程序调入内存,然后才能用汇编语言源程序进行翻译加工,得到机器语言的目标程序。 4. 解释程序 解释程序的功能是把用某种程序设计语言的源程序(如BASIC程序)翻译成机器语言的目标程序。并且本着翻译一句就执行一句的原则,做到边解释边执行。 5. 编译程序 编译程序能把高级语言(如FORTRAN等)编写的源程序翻译成机器语言的目标程序。 6. 实用程序 用汇编程序和编译程序的程序设计语言,当编好程序后,还需要对程序进行编辑、调试并将程序装配到计算机中去执行;在这些过程中,还需要一些其他的辅助程序,这 类辅助程序称为实用程序。为计算机系统常用的实用程序有:文本编辑程序、连接程序、定位程序和调试程序。 文本编辑程序(EDITOR)是软件编制开发的一种工具。在它的管理控制下,程序员可通过键盘/屏幕终端(CRT终端)输入源程序,然后存入磁盘,生成文本文件,并由它对生成的文本文件进行编辑—如增补、删除、修改等。 微计算机常采用模块结构方式进行程序设计。模块程序允许将一个大的程序分为若干个独立的模块进行编程。各模块经汇编后,得到各自独立的的目标程序。这些目标程序都是具有浮动地址格式的机器语言程序,还不能被机器执行。连接程序的功能就是把各个独立的具有浮动地址的机器语言模块组合起来,形成一个完整的输出程序,再由定位程序把存储器单元分配给目标模块,这时的输出程序方能有计算机执行。 一个程序编好以后,必须要进行调试。一般语法上的错误在汇编、编译和链接过程中可以排除,而大部分错误还必须用调试手段来进行排除。调试程序(Debug)的任务就是用来对程序错误进行纠错的。 7. 诊断程序 诊断程序的功能是用来检查程序的错误或计算机故障的,并由它之处出错的地方。 (三) 应用程序 应用程序是用户利用计算机提供的各种系统软件,为解决各种实际问题而编制的程序,随着计算机的广发应用和普及,现已编制出许多应用程序,这些应用程序可按功能组成不同的程序包(Routine Package),以减少重复的编程工作。 (四) 数据库与数据库管理系统 随着计算机硬件和软件的发展,微计算机在硬件处理、情报检索以及各种管理系统中的应用越来越普及和深入。在这样的数据处理系统中,需要处理大量的数据,检索和建立大量的各种各样的表格,这些数据和表格按一定的形式和规律加以组织,建立数据模型,实行集中管理,于是就建立了数据库(简称DBASE)为了便于用户根据需要建立自己的数据库,对库中的内容进行询问、显示、修改以及输出打印各种表格等等,这就建立了数据库管理系统DBMS(DATA BASE Management System)。DBASE II、DBASE III和FOXBASE都是使用方便而得到普遍采用的软件。 上述各种形式的程序统称为软件。没有软件的计算机称裸机,裸机不能提供使用。相反,丰富的软件是对硬件功能的强有力扩充。将各种程序存储在各种存储介质,例如ROM芯片、纸带、卡片、磁带、磁盘等中,可构成商业化的软件产业。 1.3.3(主要性能指标和常用术语 位、字节、字及字长是计算机常用的名词术语。 (1)位(Bit) “位”是指一个二进制位。它是计算机中信息存储的最小单位,一般用b表示。 (2)字节(Byte) “字节”是指相邻的8个二进制位。1024个字节构成1个千字节,用KB表示。1024KB构成1兆字节,用MB表示。1024MB构成1个千兆(吉)字节,用GB表示。B、KB、MB、GB、都是计算机存储器容量的单位。 (3)字(Word)和字长 “字”是计算机内部进行数据传递处理的基本单位通常它与计算机内部的寄存器、运算装置、总线宽度相一致。 一个字所包含的二进制位数称为字长。常见的微型计算机的字长有8位、16位、32位和64位之分。 但是,目前在PC机中,把字(Word)定义为2字节(16位),双字节(Double World)为4字节(32位),四字节(Quad Word)为8字节(64位)。 1.4 多媒体计算机 媒体(Media)即是信息传播的载体,如图像(Image)、声音(Audio)、文字(text )等。利用计算机来处理信息媒体已有了很长的历史,并形成了成熟的理论方法,如图像处理技术现在已有了较成熟的图像采集、压缩存储以及多种处理理论。但是把多媒体,如视频(Video)、声音、图像、动画(Animation)、文字结合在一起,进行同时处理却是近几年的事,这边形成了一种新技术——多媒体(Multimedia)。通常所说的多媒体是指多媒体计算机技术(Multimedia Computing),简称多媒体技术,其涵义是利用计算机来综合、集成地处理文字、图形、图像、声音、视频、动画等媒体,而形成的一 种全新的信息传播和处理技术。它把计算机技术、通信技术和广播、点事技术融为一体,综合利用,扩展了计算机应用的领域,受到了人们极大的关注和重视。 1.4.1.多媒体技术 1.4.2.多媒体计算机的组成 多媒体计算机(MPC)是多媒体技术走向实用化的范例,它是在PC机的基础上融合高质量的图形、立体声、动画等媒体而组合的系统,其硬件结构如下图所示。 总之,多媒体计算机是在通用的PC机的基础上,增加了多媒体设备和多媒体软件构成的。本小节不讨论软件,所以在普通台式极端及基础上增加了多媒体设备就构成了多媒体计算机的硬件系统。 2.1 微处理器的发展 在巨型机、大型机、小型机和微机等各类计算机中,微机(Microcomputer)是性能、价格、体积较小的一类,常用在科学计算、信息管理、自动控制、人工智能等领域。工作学习中使用的个人微机,生产生活中运用的各种智能化电子设备都是典型的微机系统。 危机的运算和控制的核心,即所谓的中央处理单元(Central Processing Unit CPU),被称为微处理器(Microprocessor)。它是一块大规模集成电路芯片,代表着整个微机系统的性能。所以,通常就采用微处理器为核心构造的计算机称为微机。 2.1.1微处理器历史 微处理器的性能经常用字长、时钟频率、集成度等基本的技术参数来反映。字长(Word)表明微处理器每个时间单位可以处理的二进制数据位数,例如一次进行运算、传输的位数。时钟频率表明微处理器的处理速度,反映了微处理器的基本时间单位。集成度表明微处理器的生产工艺水平,通常用芯片上的晶体管数量来表达。 1. 通用微处理器 1971年,美国Intel公司(英特尔)公司为日本制造商设计了一个微处理器芯片。该芯片成为世界上第一个微处理器4004。它字长4位,集成了约2300个晶体管,时钟频率为108kHz(和字)。以它为核心的MCS-4计算机也就是世界上第一台微型计算机。4004随后被改进为4040。 1972年Intel公司研制出字长8位的微处理器芯片8008,其时钟频率为500kHz,集成度约为3500个晶体管。随后的几年当中,微处理器开始走向成熟,出现了以Motorola公司M6800、Zilog公司Z80和Intel公司8080/8085为代表的中、高档8位微处理器。Apple公司苹果机就是这一时期著名的个人微型机。 1978年开始,各公司相继推出一批16位字长的微处理器,如Intel公司的8086和8088、Motorola公司的M6800、Zilog公司的Z8000等。例如Intel 8086的时钟频率为5MHz,集成度达到2.9万个晶体管。这一时期的著名微机产品是IBM公司采用Intel公司的微处理器、Microsoft(微软)公司的操作系统开发的16位个人计算机(Personal Computer,PC)。 1985年,公司借助IBM PC的巨大成功,进一步推出了32位微处理器80386,其集成度高达27.5万个晶体管,时钟频率达16MHz。从这时起,微处理器步入快速发展阶段。就Inter公司来生说,就陆续研制生产了80486、Pentium(奔腾)、Pentium Pro (高能奔腾)、MMX Pentium(多能奔腾)、PentiumII、Pentium?和Pentium4等微处理器。 2000年,Inter公司在微机高端产品服务中使用了字长64 位的新一代微处理器Itanium(安腾)。事实上,其他公司的64位微处理器在20世纪90年代已经出现,但也是主要应用于服务器产品中,不能与通用80x86微处理器兼容。2003年4月,AMD公司推出首款兼容32位80x86结构的64位微处理器,被称为x86-64结构。2004年3月,Inter公司也发布了首款扩展64位能力的32位微处理器,它采用扩展64位主存技术(Extended Memory 64 Technology,EM64T)。64位微处理器主要将整数运算和主存寻址能力扩大到64位。2005年,64PC机除露端倪,逐渐获得用户青睐。 2. 专用处理器 除了装在PC、笔记本电脑、工作站、服务器上的通用微处理器(常简称为MPU),还有其他应用领域的专用处理器:单片机(微控制器)和数字信号处理器。 单片机(Single Chip Microcomputer)是指通常用于控制领域的微处理芯片,其内部除了CPU还集成了计算机的其他一些主要部件,如只读存储器(Read-Only Memory,ROM)、随机存储器(Random Access Memory,RAM)、计时器、并行接口和串行接口,有的芯片还集成了A/D、D/A转换电路等。换句或说,一个芯片几乎就是一个计算机,只要配上少量的外部电路和设备,就可以构成具体的应用系统。 单片机是国内习惯的名称,国际上多称为微控制器(Micro Controller)或嵌入式微控制器(Embedded Controller),简称为MCU。微控制器的初期阶段(1976-1978年)以Inter公司的8位MCS-48系列为代表。1978年以后,微控制器进入普及阶段,以8位为主,最著名的是Inter公司的MCS-51系列,还有Atmil(爱特梅尔)公司的AT89系列(与MCS-51兼容)、Microchip Technology公司的PIC系列单片机。1982年以后高性能的16位、32位微控制器出现,例如Inter公司的MCS-96/98系列、Atml公司的AT91系列(基于ARM内核)。 数字信号处理器(Digital Signal Processor),简称DSP芯片,实际上也是一种微控制器(单片机),但更专注于数字信号大的高速处理,内部集成有高速乘法器,能够进行快速乘法和加法运算。DSP芯片自1979年Inter公司开发2920以后也经历了多带代展,其中美国德州仪器(Texas Instruments,TI)公司TMS320 各代产品具有代表性,例如1982年的TMS2010、1985年的TMS320C20、1987年的TMS320C30、1991年的TMS320C40,还有TMS320C2000/TMS320C5000/TMS320C6000系列等。DSP芯片市场主要分布在通信、消费类电子产品和计算机。我国推广和应用较多的是IT公司、AD公司和Motorola公司的DSP芯片。 利用微控制器、数字信号处理器或通用微处理器,结合具体应用就可以构成一个控制系统,例如当前主要的应用形式是嵌入式系统。嵌入式系统融合了计算机的软硬件技术、通信技术和半导体微电子技术,把计算机直接嵌入到应用系统中,构造信息技术(Information Technology,IT)的最终产品。嵌入式系统有三个级别的体系结构。 ? IP级结构(Intellectual Property,IP,知识产权):也就是片上系统SoC(Systemon Chip)形式。他把不同的IP单元,根据应用要求集成在一个芯片上,各种嵌入式软件也能以IP方式集成在芯片中。 ? 芯片级结构:目前最常见的嵌入式系统形式。它根据各种IT产品的要求,选用相应的处理器芯片(MCU、DSP、MPU等)、RAM和ROM,以及I/O接口芯片等组成相应的嵌入式系统,相应的系统软件和应用软件也固化在ROMA中。 ? 模块级结构:以80x86 微处理器构成的计算机模块嵌入到应用系统中。 自从20世纪70年代微处理器产生以来,塔基一直沿用着通用CPU、微控制器和DSP芯片三个方向发展。这三类微处理器基本工作原理一样,但各有其特点,技术上它们不断地相互借鉴和交融,应用上却大不相同。本 关于书的成语关于读书的排比句社区图书漂流公约怎么写关于读书的小报汉书pdf 以通用微处理器80x86和以其构成的PC微机为蓝本展开教学,基本原理也适用于其他微处理器应用系统,可以认为是是其他微处理器的一个基础知识。学习微控制器和DSP芯片构成的专用应用系统需要另外的课程和教材。 2.4 8086/8088 CPU的引脚功能 8086/8088 CPU均属高性能微处理器,根据它的基本性能至少包含16条数据线和20条地址线,再加上其他一些必要的控制信号。由于芯片引脚线数量不能太多,因此对部分引脚采用了分时复用方式,构成40条引脚的双列直插式封装。8086CPU封装外形与内部个功能部件之间相互联系如图3-4所示。 由于8086/8088 CPU具有两种工作模式(最小模式和最大模式),8条引脚(24-31脚)在两种工作模式中,具有不同的功能,图3-4(a)括号中所示为最大模式下被重新定义的控制信号。 下面对各引脚功能作简要说明: 1.AD15,AD0 (Address Data Bus) 分时复用的地址数据线,传送地址时三态输出,传送数据时可双向三态输入/输出。 2. A/S,A/S(Address /Status) 196163 分时复用的地址状态线,作用地址时,A,A与AD,AD一起构成访问存储器的20位1916150 物理地址。当CPU访问I/O端口时,A,A保持为“0”。1916 作状态线时,S,S用来输入状态信息,其中:S和S可用于表示当前使用的段寄存器6 334 号,如表3-1所示。当S S时,表示当前正使用CS对存储器寻址,而当前正对I/O端43 口或中断矢量寻址时,不需要使用寄存器。 (表格) 数据用来表示中断标志位状态。当IF=1时,S置“1”; S恒保持位“0”。 56 3.BEH/ S(Bus High Enable/Status) 总线高字节有效信号,三态输出,低电平有效。7 用来表示当前高8位数据总线上的数据有效。读/写存储器或I/O端口以及中断响应时,BEH用来作选体信号,与最低位地址码*****配合表示当前总线使用情况,如表3-2所示。 (表格a 表格b) 非数据传送期间,输出S状态信息,在CPU处于保持响应期间被设置为高阻状态。 7 4. RD(Read) 读信号,三态输出,低电平有效。表示当前CPU正在读存储器或I/O端口。 5. WR(Write) 写信号,三态输出,低电平有效。表示当前CPU正在写存储器或I/O端口。 7. READY 准备就绪信号,由外部输入,高电平有效,表示CPU访问的存储器或I/O端口已经为传送做好准备。当READY无效时,要求CPU插入一个或几个等待周期*****直到READY有效为止。 8. INTR(Interrupt Request) 中断请求信号,由外部输入,电平触发,高电平有效。INTR有效时,表示外部向CPU发出中断请求。COU在每条指令的最后一个时钟周期对INTR进行测试,一旦测试到有中断请求,并且当前中断允许标志IF=1时,则暂停执行下条指令转入中断响应周期。 9. INTA(Interrupt Acknowledge) 中断响应信号,由外部输入,低电平有效。表示CPU响应了外部发来的INTR信号,在中断响应周期,可用来作为读选通信号。 10. NMI(Non-Mackable Interrupt Reguest) 不可屏蔽中断请求信号,由外部输入,边沿触发,正跳沿有效。不受中断允许标志的限制,CPU一旦测试到NMI请求有效,待当前指令执行完成就自动从中断入口地址表中找到类型2中断服务程序的入口地址,并转去执行,显然这是一种比INTR高级的请求。 11.TEST 测试信号,由外部输入,高电平有效。当CPU执行WAIT指令时,每隔5个时钟周期对TEST进行一次测试。若测试到TEST无效,则CPU处于踏步等待状态,直到TEST有效,CPU才继续执行下一条指令。 12.RESET 复位信号,由外部输入,高电平有效。RESET信号至少保持4个时钟周期。CPU接收到RESET信号后吗,停止进行操作,并将标志寄存器、段寄存器、指令指针IP和指令队列等复位到初始状态。 13.ALE(Address Latch Enable) 地址所存允许信号,向外部传输,高电平有效。在最小模式系统中用来作地址锁存器8282/8283的选通信号。 14.DT/R( Data Transmit/Receive) 数据发送/接收控制信号,三态输出。在最小模式系统中用来控制数据收发器8286/8287的数据传送方向。当DT/R为高电平时, 表示数据从CPU想不输出,即完成写作操作,DR/R为低电平时,表示数据从外部向CPU输入,即完成读操作。 15.DEN(Data Enable) 数据允许信号,三态输出,低电平有效。在最小模式系统中用来做数据收发器8286/8287的选通信号。 16.HOLD(Hold Request) 数据请求信号,三态输出,由外部传输,高电平有效。在最小模式系统中表示有其他共享总线的主控者向CPU请求使用总线。 17. HLDA(Hold Acknowlege) 总线响应信号,向外部传输,高电平有效。CPU一旦检测到由HOLD请求时,就在当前总线周期结束时,使HLDA有效,表示响应这一总线请求,并立即让出总线使用权。CPU中指令执行部件(EU)可继续工作到下一次要求使用总线为止,一直到HOLD无效,CPU才将HLDA置成无效,并回收对总线的使用权,继续操作。 18. MN/MX(Miniumn/Maximun) 工作模式选择信号,由外部输入。MN/MX为高电平,表示CPU工作在最小模式系统中,MN/MX为低电平时,表示CPU工作在最大模式系统中。 19. CLK(Clock) 主时钟信号,由8284时钟发生器输入。8086CPU可使用的时钟频率随芯片型号不同而异,8086为5MHz,8086-1为10MHz,8086-2为8MHz。 20.Vcc(电源) 8086CPU只需要单一的+5伏电源,由Vcc输入。 2.5 8086/8088总线结构 总线:计算机传送信息的一组信号线; 单向总线:只能向一个方向传送信息的总线‘ 双向总线:能向两个方向传送信息的总线; 微型计算机一般采用三总线,即按传输信息的性质分为三总线:地址总线、数据总线、控制状态总线。这样模块之间的连接就既方便,又易于扩展,便于构成多机系统。 微处理器内部总线 把内部寄存器组、累加器,算术逻辑单元和控制器部件集成在5x5,,芯片上,为了提高集成度采用了内部数据总线。 单机内部总线 微型计算机内部系统板与插件板之间进行通信的总线,称为系统总线。如IBM-PC总线,AT总线等。CPU与外围芯片之间的总线称为内总线(局部总线)。 外总线:(多机之间) 微型计算机和其他设备或控制对象之间进行通信的总线叫外总线。有IEEE-488标准总线,EIA-RS232异步和同步通信标准总线MULTIBUS多总线等。 2.6 INTEL 8086 微处理的典型时序 目前在构成微型计算机硬件系统时,所连接的存储器和I/O接口电路的数量较多,8086微处理器。通常工作在最大组态。所以,所介绍的时序是以8086工作在最大组态为基础的。 在最大组台下,8086的基本总线周期由4个T状态组成。T状态时,8086发出1 ——————————20位地址信号,同时送出状态信号S 、S、S给8288总线控制器。8288对S~S01202进行译码,产生相应命令的输出控制信号。首先,8288在T期间送出地址锁存允许信1 号ALE,将CPU输出的地址信号所存至地址锁存器中,再输出到系统地址总线上。 在T状态,8086开始执行数据传送操作。此时,8086内部的多路开关进行切换,2 将地址/数据线AD~AD上的地址撤销,切换成数据总线,唯独写数据做准备。8288015 —发出数据总线允许信号和数据发送/接受控制信号DT/R允许数据发生器工作,是数据总线与8086的数据线接通,并控制数据传送方向。同时,把地址/状态线A/S~A/S163196切换成与总线周期有关的状态信息,指示若干与周期有关的情况。 在T周期开始的始终下降沿上,8086采样READY线。如果READY信号有效(高3 电平),则在T状态结束后进入T状态,在T状态开始的时钟下降沿,把数据总线上344 的数据读入CPU或写进地址选中的单元。在T状态,结束总线周期。如果访问的是慢4 速存储器或外设接口,则应该在T状态输出的地址经过译码选中某个单元或设备后,1 立即驱动READY信号到低电平。8086在T状态采样到READY信号无效,就会插入等3 待周期T,在T状态CPU继续采样READY信号;直至其变为有效后再进入T状态,wW4完成数据传送,结束总线周期。 ————在T4状态,8086完成数据转送,状态信号S~S变为无操作的过渡状态。在此期02 间,8086结束总线周期,恢复各信号线的初态,准备执行下一个总线周期。 2.8.1 80286 1982年,Intel公司推出仍为16位字长的80286微处理器,单地址总线扩展为24位,即主存储器具有16MB的容量。80286设计有与8086工作方式一样的实方式(Real Mode),还有保护方式(Protected Mode)。在保护方式下,80286提供了储存管理、保护机制和多任务管理的硬件支持。这些传统上由操作系统实现的功能在处理器硬件支持下,是微机系统的性能得到极大的提高。 2.8.2 80386 1985年,Inter公司80x86微处理器进入第三代80386.80386微处理器采用32位 30结构,数据总线32位,地址总线也是32位,可寻址4GB主存(1GB=2B=1024MB),时钟频率有16、25和33MHZ.作为32位微处理器,80386设计得非常成功。当时,Inter公司明确宣布80386芯片的体系结构将被确认为以后开发的80x86系列微处理器的标准,称为英特尔32位结构:IA-32(Inter Architeture-32)。IA-32至临汾系统全面升级为32位,但仍然兼容原16位指令系统。 80386除保持与80286兼容外,又提供了虚拟8086工作方式(Vitual 8086 Mode).虚拟8086方式是在保护方式下的一种特殊状态,类似8086工作方式但又接受保护方式的管理,能够模拟多个8086处理器。32位PC机的Windows操作系统采用保护方式,其MS-DOS命令行(环境)就是虚拟8086方式,而早期采用的DOS操作系统是以实方式为基础建立的。 为了适应便携机要求,Inter公司在1990年生产的低功耗节能型芯片中,增加了一种新的工作状态:系统管理方式(System Managemeng Mode,SMM)。它是指档处理 器进入这种状态后,微处理器会根据当时不同的使用环境,自动减速进行,甚至停止运行。这是微处理器还可以控制其他部件停止工作,从而使微机的整体耗电降到最小。 2.8.3 80486 1989年,Inter公司推出了80486微处理器。从结构上来说80486=80386+80387+8KB Cache,即80486吧80386微处理器与80387数学协处理器和8KB高速缓冲存储器(Cache)集成在一个芯片上,是微处理器的性能大大提高。为了协助微处理器处理浮点数据,Inter公司设计有数学协处理器,后被称为浮点处理单元(Floating-Point Unit,FPU)。配合8086和8088的是8087,配合80286的是80287,配合80386的是80387。而从80486开始,FPU已经被集成到一个人微处理器当中。高速缓冲存储器是微处理器与主存之间速度很快但容量较小的存储器,可以有效地提高整个系统的存取速度。80486不仅在芯片内部集成有8KB第一级高速缓存(L1 Cache),而且支持外部第二级高速缓存(L2 Cache)。 Inter80x86系列微处理器是传统的复杂指令集计算机(Complex Instruction Set Computer,CISC),它采用大量的、复杂的但功能强大的指令来提高性能。复杂指令一方面提高了处理器性能,另一方面给进一步提高提高性能带来了麻烦。所以,人们又转而设计主要由简单指令组成的处理器,以期在新的技术条件下生产更高性能的处理器,这就是精简指令集计算机(Redeced Instruction Set Computer,RISC)。80486及以后IA-32微处理器吸取RISC技术特长将其融入CISC中,同时采用流水线方式的指令重叠执行方法,从而使80486可以在一个时钟周期执行完成一条简单指令。指令流水线技术是将指令的执行划分成多个步骤,在多个部件中独立地进行,这样使得多条指令可以在不同的执行阶段同时进行,就像工厂中的产品流水线。 80486DX4综合了此前所使用的所有技术,是80486微处理器中最快的一种芯片。它采用时钟倍频(Clock Doubleling)思想,将外部时钟频率25MHz或33MHz提高3倍作为内部工作时钟频率,形成75MHz或100MHz两款产品。以前的微机系统中,微处理器的内、外部时钟频率是一样的,同时也就是处理器与外围部件的数据传输频率。当微处理器的时钟频率提高了,系统的运行速度当然也就提高了。但是,当外部数据传输频率太高时,会给外围部件、主板等设计带来困难。为了既能尽量提高微处理器的时钟频率以增强性能,又能迁就较慢速的外围部件,是高频率的微处理器照样能够使用,Inter公司采取这种时钟倍频技术。 2.8.4 PENTIUM Pentium芯片即俗称的80586微处理器,因为数字很难进行商标版权保护的缘故而特意取名。其实,Pentium源于希腊文“pente”(数字5),加上后缀-ium(化学元素周期表命名元素常用的后缀)变化而来的。同时,Inter公司为其取了一个响亮的中文名字“奔腾”,并进行了商标注册。为了满足不断发展的应用和市场要求,这一代80x86微处理器形成了Pentium系列芯片。 Inter公司于1993年制造成功Pentium。其内部时钟频率有120、133、166和200MHz等多款,外部频率主要是60MHz和66MHz。Pentium虽然仍属于32位结构,但其与主存连接的外部数据总线却是64位的,这样大大提高了存取主存的速度。 Pentium引入了超标量(Superscalar)技术,内部具有可以并行工作的2条数据处理流水线,可以达到每个周期执行2条指令。Pentium还将L1Cache分成两个彼此独立的8KB数据告诉缓冲储存器,即双路高速缓冲结构,这种结构可以减少争用Cache的情况。另外,Pentium对浮点处理单元做了重大改进,包含了专用的加法、乘法和除法单元。Pentium还对常用的简单指令直接用硬件逻辑实现,对指令的微代码进行了重新设计。这些都提高了Pentium的整体性能。 3.1 指令系统概述 3.1.1.指令格式 当指令用符号表示时,就是使用IA-32汇编语言的子集。在此子集中,指令有以下格式: label(标号):mnemonic(助记符)argument1(参数1),argument2(参数2),argument3(参数3) 其中: (1) 标号(label)是一个标识符后面跟有冒号(:); (2) 助记符(mnemonic)是一类具有相同功能的指令操作码的保留名; (3) 操作数参数1(argument1)、参数2(argument2)和参数3(argument3)是任选的,可以有零到三个操作数,操作数参数的数量取决于操作码。若存在操作数参数,它们可能是文字或数据项的标识符。操作数标识符或者寄存器的保留名或者是在程序的另一部分中声明的赋予数据项的标识符。 当在算术和逻辑指令中存在两个操作数时,右边的操作数是源,左边的操作数是目的。 例如: LOADREG:MOV EAX,SUBTOTAL 在此例中,LOADREG是标号,MOV是操作码的助记标识符,EAX是目的的操作数而SUBTOTAL是源操作数。 这条指令的功能是:把由SUBTOTAL表示的源操作数传送(MOVE)至EAV寄存器。 3.3 INTEL 80×86指令系统 这一部分我们重点介绍8086的指令。 8086的指令系统可以分成如下6个功能组: (1)数据传送(Data transfer); (2)算术运算(Arithmetic); (3)逻辑运算(Logic) (4)串操作(String manipulation) (5)控制传送(Control transfer) (6)处理器控制(Processor control) 下面我们就分这6个方面来介绍8086的指令系统,并通过一些例子说明这些指令的使用。 在介绍指令以前,我们先把在指令中要出现的一些符号介绍一下: AH、AL、BH、CH、CL、DH、DL 8位寄存器 AX、BX、DX、DX、SP、BP、SI、DI 16位通用寄存器 SP 堆栈指针 IP(或PC) 指令指针 Flags 标志位 DI,SI 目的和源变址寄存器 CS、DS、ES、SS 段寄存器 r 通用寄存器器组(如AX等或AL等,取决于操作数的长度而定) a AL或AX(取决于操作数的长度) src,dst 源和目的操作数。所有下列的寻址方式都是可用的: [BX+SI+n] [BX+DI+n] [BP+DI+n] [BP+SI+n] [SI+n] [DI+n] [BP+n] [BX+n] [n] R ADR(src) 源操作数的地址 [] 存储单元的内容(正常在数据段) ES:[] 附加存储段的内容 OPRD 操作数 seg 段寄存器(CS、DS、ES、SS) im 立即数 n 8位 nn 16位 nnnn 32位 3.3.1.数据传送类 数据传送是计算机最基本、最重要的一种操作,在实际程序中,数据传送指令使用的比例是最高的。所以,数据传送是否方便灵活,速度是否快,是指令系统要考虑的重要问题。 数据传送指令又可以分为以下四种: (1)通用数据传送指令 (2) 累加器专用数据传送指令; (3) (4) 标志数据传送指令。 这一类指令,除了SAHF和POPF指令以外,对标志位没有影响。 1.通用传送指令(GENERAL PURPOSE TRANSFER) 8086提供方便、灵活的通用的数据传送操作,这些指令适用于大多数操作数。只有这种通用传送指令(除了XCHG以外),才是惟一的允许以段寄存器作为操作数的指令。 (1) MOV OPRD1(目的),OPRD2(源) 它把一个字节(用B表示)或字(用W表示)操作数从源传送至目的 MOV nn,a B/W (nn)= a MOV a,nn B/W a =(nn) MOV seg,src w seg = src MOV dst,seg w dst = seg MOV r,src B/W r = src MOV dst,r B/W dst = r MOV r,im B/W r = im MOV dst,im B/W dst = im 具体的来说,这一条通用的数据传送指令,能实现以下操作: ? CPU内部寄存器之间数据的任意传送(除了码段寄存器CS和指令指针IP以外)。 例如: MOV AL,BL ? 立即数传送至CPU内部的通用寄存器组(即AX、BX、CX、DX、BP、SP、SI、DI),给这些寄存器赋初值。 例如: MOV CL,4 MOV AX,03FFH ? CPU内部寄存器(除了CS和IP以外)与存储器(所有寻址方式)之间的数据传送,可以实现一个字节或一个字的传送。 CPU的通用寄存器可以与寄存器之间实现数据传送。 例如: MOV AL,BUFFER MOV AX,[SI] 还可以实现段寄存器(除CS以外)与存储器之间的数据传送。 例如: MOV DS,DAT[SI+BX] MOV DEST[BP+DI],ES 但是,MOV指令不能实现存储单元之间的数据传送。若我们需要把地址(即段内的地址位移量)为AREA1的存储单元的内容,传送至同一段内地址为AREA2的存储单元中去,MOV指令不能直接完成这样的传送,但我们可以用CPU的内部寄存器为桥梁来完成这样的传送,可以采用如下指令: MOV AL,AREA1 MOV AREA2,Al 若要求这样传送的不是一个字节,而是一个数据块,例如100个数据,如何实现呢, 当然可以采用与上述类似的200条指令来完成100个数据的传送。这些指令的操作是重复的,但每条指令的地址是变化的。为了简化程序的编制,当然希望利用循环程序,但困难在于每一次循环时要修改地址(源地址和目的地址),于是就要把地址放在寄存器对中,用寄存器间接寻址来寻找操作数。而寄存器的内容易于修改,就可以实现对地址的修改。再把循环次数的控制部分考虑进去,就可以得到如下程序: MOV SI,OFFSET AREA1 MOV DI,OFFSET AREA1 MOV CS,100 AGAIGN: MOV AL,[SI] MOV [DI],AL INC SI INC DI DEC CX JNZ AGAIN 其中的增量(INC),减量(DEC)指令以及转移指令(JNZ),我们可将在后面详细介绍。 OFFSET AREA1是指地址单元AREA1在段内的地址偏移量。如上所述,在8086中要寻找内存操作数时,必须以段地址(在某个段寄存器中)加上此单元的段内地址偏移量,才能确定某一内存单元的物理地址。 在下面为了说明指令的功能所举的程序例子中,我们只说明可执行指令部分,也就是8086指令系统中的指令。一个完整的程序所要用到的伪指令等,我们将在下一章中介绍。但为了便于在机器中运行此程序,在程序清单中,我们给出了必须的伪指令 ? 能实现用立即数给存储单元赋初值。 MOV操作数 MOV码举例 存储器,累加器 MOV ARRAY[SI],AL 累加器,存储器 MOV AX,TEMP_RESULT 寄存器,寄存器 MOV AX,CX 寄存器,存储器 MOV BP,STACK_TOP 存储器,寄存器 MOV COUNT[DI],CX 寄存器,立即数 MOV CL,2 存储器,立即数 MOV MASK[BX][SI],2CH 段寄存器,16位寄存器 MOV ES,CX 段寄存器,存储器 MOV DS,SEGMENY_BASE 寄存器,段寄存器 MOV BP,SS 存储器,段寄存器 MOV [BX]SEG_SAVE,CS (2) 堆栈操作指令 ? PUSH OPRD 入栈指令,操作数的长度必然为字,在入栈操作时,把一个字从源操作数传送至由SP所指向的堆栈的顶部,例如: PUSH AX PUSH BX 每个指令又分以下两步执行: 首先SP-1?SP,然后把AH(寄存器中的高位字节)送至SP所指的单元; 再次使SP-1?SP,把AL(寄存器中的低位字节)送至SP所指的单元。 随着推入内容的增加,堆栈就扩展,SP值减小,但每次操作完,SP总是指向堆栈的顶部。堆栈的最大容量即为SP的初值与SS之间的距离。 在子程序调用和中断时,断点地址的入栈保护与上述的PUSH指令的操作相同。但它们是由子程序调用指令或中断响应来完成的。 堆栈操作指令,可以用来保护现场,或临时保存某一个字。 总之,入栈操作是把一个字的源操作数,送至堆栈的顶部,并且在数据传送操作的同时,要相应地修改SP ,执行一次入栈指令使SP-2?SP。具体入栈指令如下: PUSH r W SP = SP – 2,(SP) = r PUSH seg W SP = SP – 2,(SP) = seg PUSH src W SP = SP – 2,(SP) = src 即源操作数可以是CPU内部的通用寄存器、段寄存器(除CS以外)和内存操作数(可用各种寻址方式)。 入栈指令的使用举例,如下 PUSH操作数 PUSH码举例 此存起 PUSH SI 段寄存器(CS非法) PUSH ES 存储器 PUSH RETURN_CODE[SI] ? POP OPRD 出栈指令,把现行SP所指向的堆栈顶部的一个字,送至指定的目的操作数;同时进行修改堆栈指针的操作,即SP+2?SP。 具体的出栈指令如下: POP r W r=(SP),SP=SP+2 POP seg W seg=(SP),SP=SP+2 POP dst W dst=(SP),SP=SP+2 这些指令的使用举例,如下 POP操作数 POP码举例 寄存器 POP DX 段寄存器(CS非法) POP DS 存储器 POP PARAMETER (3) 交换指令 XCHG OPRD1(目的),OPRD2(源) 这是一条交换指令,把一个字节或一个字的源操作数与目的操作数相互交换。交换能在通用寄存器与累加器之间、通用寄存器之间、通用寄存器与存储器之间进行,但段寄存器不能作为一个操作数进行交换。 具体的指令如下: XCHG AX,r W r=AX,AX=r XCHG r,src B/W r=src,src=r 例如: XCHG AL,CL XCHG AX,DI XCHG AX,BUFFER 这些指令的使用举例,如下: XCHG操作数 XCHG码举例 累加器,寄存器 XCHG AX,BX 存储器,寄存器 XCHG SEMAPHORE,AX 寄存器,寄存器 XCHG, AL,BL 2. 累加器专用传送指令 有三条累加器专用的传送指令: (1) IN 输入指令,允许把一个字节或一个字由一个输入端口(port),传送至AL(若是一个字节)或AX (若是一个字)。一个计算机可以配接许多外部设备,每个外部设备与CPU之间要交换数据,状态信息和控制命令,每一种这样的信息交换都要通过一个端口来进行。系统中端口像存储器中那样也用地址来区分。端口地址若是由指令中的n所规定,则可寻址port0,port255,共256个输入端口;端口地址也可包括在寄存器DX中,则允许寻址64K个输入端口。 具体指令如下: IN AL,n B AL=[n] IN AX,n W AX=[n+1][n] IN AL,DX B AL=[DX] IN AX,DX W AX=[DX+1][DX] 指令的使用举例: IN操作数 IN码举例 累加器,立即地址 IN AL,0EAH 累加器,DX IN AX,DX (2) OUT 输出指令,是把在AL中的一个字节或在AX中的一个字,传送至一个输出端口。端口寻址方式与IN指令相同。具体指令如下: OUT n,AL B AL?[n] OUT n,AX W AL?[n],[n+1] OUT DX,AL B AL?[DX] OUT DX,AX W AL?[DX],[DX+1] OUT操作数 OUT码举例 8位立即地址,累加器 OUT 44,AX DX,累加器 OUT DX,AL (3) XLAT 这条指令完成一个字节的查表转换。寄存器AL的内容作为一个256个字节的表的下标。这个表的基地址在寄存器BX中,转换后的一个字节的操作数放在AL中。 指令格式为: XLAT B AL=[BX+AL] 例如:数字0~9对应的格雷码为18H、34H、05H、06H、09H、0AH、0CH、11H、12H和14H。若某一个端口输入给CPU一位十进制数码,要求CPU把它转换为相应的格雷码,再输送给这个端口。 要实现这样的转换,可以把格雷码按照十进制数的次序排成一个表放在内存的某一个区域中,把此区域的地址送至BX。CPU从指定端口(例如端口号为1)输入一个字节至AL,然后利用查表指令XLAT从格雷表中查到相应的格雷码,再通过同一个端口输出。 MOV BX,TABLE IN AL,1 XLAT TABLE OUT 1,AL 指令的使用举例: XLAT操作数 XLAT码举例 源表 XLAT ASCII TAB 3. 地址 目的传送(ADDRESS OBJECT TRANSFERS) 8086中有三种地址 目的传送操作指令。 (1) LEA(Load Effective Address) 这条指令把源操作数的地址偏移量,传送至目的操作数。源操作数必须是一个内存操作数;目的操作数必须是一个16位的通用寄存器。这条指令常用来建立操作所需要的寄存器地址指针。 LEA r,src r=ADR(src) 前面例子中所用到的指令 MOV SI,OFFSET AREA1 就可以用指令 LEA SI,AREA1 来代替。 指令的使用举例,如下: LEA操作数 LEA码举例 16位寄存器,16位存储器 LEA BX,[BP][DI] (2) LDS(Load pointer into DS) 这条指令是传送一个目标指针(即一个32位的目标,它包括一个段地址和一个地址偏移量),从源操作数(它必须是一个内存操作数)传送至一对目的寄存器。目的的段地址必须传送至DS段寄存器;而16位地址偏移量,必须传送至一个16位的指针寄存器或变址寄存器如下图所示: 指令格式为: LDS r,src DW r?(EA),DS?(EA+2) 指令的使用举例,如下: LDS操作数 LDS码举例 16位寄存器,32位寄存器 LES SI,DATA SEG[DI] (3) LES(Load Pointer into ES) 这条指令除了把目标段地址送至段寄存器ES以外,其他与LDS指令类似。 LES r,src r?(EA),ES?(EA+2) 指令的使用举例,如下: LES操作数 LES码举例 16位寄存器,32位存储器 LES DI[BX]TEXT_BUFF 4. 标志寄存器传送(FLAG REGISTER TRANSFERS) 8086有四条标志传送操作指令。 (1) LAHF(Load AH with Flags) 这条指令把标志寄存器中的符号标志S、零标志Z、辅助进位标志A、奇偶标志P和进位标志C传送至AH的指定位,即相应地传送位至位7、位6、位4、位2和位0,而位5、位3、位1的内容没有定义。 这条传送指令本身并不影响这些标志位。 指令的使用举例,如下: LAHF操作数 LAHF码举例 无操作数 LAHF (2) SAHF(Store AH into Flags) 这条指令与上一条指令的操作刚好相反,它是把寄存器AH的指定位,传送至标志寄存器中的S、Z、A、P和C标志。因而这些标志的内容就要受到影响,并且取决于AH中相应位的状态。但这条指令并不影响溢出标志O、方向标志D、中断屏蔽标志I和追踪标志T。 指令的使用举例,如下: SAHF操作数 SAHF码举例 无操作数 SAHF (3) PUSHF(Push Flags) 这条指令把整个标志寄存器(包括全部九个标志)推入至堆栈指针所指的堆栈的顶部,同时修改堆栈指针,即SP-2?SP。 这条传送指令本身并不影响这些标志位。 指令的使用举例,如下: PUSHF操作数 PUSHF码举例 无操作数 PUSHF (4) POPF(Pop Flags) 这条指令把现行堆栈指针所指的一个字,传送给标志寄存器,同时相应地修改堆栈指针,即SP+2?SP。 这条指令执行后,8086的标志位就取决于原堆栈顶部的内容。 PUSHF和POPF这两条指令可以保存和恢复标志寄存器。在子程序调用和中断服务中可以利用这两条指令来保护和恢复标志位。 另外,这两条指令也可以用来改变追踪标志T。在8086的指令系统中,没有直接能改变T标志的指令,故若要改变T标志,先用PUSHF指令将标志位入栈,然后设法改变栈顶存储单元的D8位 (把整个标志看成一个字),再用POPF指令恢复,这样其余的标志不受影响而只有T标志按照需要改变了。 这条指令的使用举例,如下: POPF操作数 POPF码举例 无操作数 POPF 3.3.2 算术运算类 8086指令系统提供加、减、乘、除四种基本的算术运算操作。这些操作都可用于字节或字的运算,也都可以用于带符号数与无符号数的运算。若是符号数,则用补码表示。 8086指令系统提供了各种校正操作指令,故可以进行组合的(即一个字节用两位BCD码表示)或未组合的(即用一位BCD码表示,其高4位为0的)十进制的算术运算。 1. 加法(ADDITION) 8086具有5种加法操作指令。 (1) ADD OPRD1,OPRD2 这条指令完成两个操作数相加,结果送至一个操作数,即OPRD1+OPRD2?OPRD1。目的操作数可以是累加器、任一通用寄存器以及存储器操作数(所有寻址方式)。 指令格式如下: ADD r,src B/W r+src?r ADD a,im B/W a+im?a ADD dst,im B/W dst+im?dst ADD dst,r B/W dst+r?dst 具体的说,可以实现累加器与立即数、累加器与任一通用寄存器、累加器与存储单元内容的相加,和放在累加器中。 例如: ADD AL,30 ADD AX,3000H ADD AX,SI ADD AL,DATA[BX] 可以实现任一通用寄存器与立即数相加,与累加器或别的寄存器相加,与存储单元的内容相加,和放在寄存器中。例如: ADD BX,3FFH ADD DX,DATA[BX+SI] 可以实现,存储操作数与立即数相加,与累加器或别的寄存器相加,和放在此存储单 元中。例如: ADD BETA[SI],100 ADD BETA[SI],AX 这些指令对标志位C、O、P、S、Z和A有影响。 这些指令的使用举例,如下: ADD操作数 ADD码举例 寄存器,寄存器 ADD CX,DX 寄存器,存储器 ADD BX,ALPHA 存储器,寄存器 ADD TEMP,CL 寄存器,立即数 ADD CL,2 存储器,立即数 ADD ALPHA,2 累加器,立即数 ADD AX,200 (2) ADC(add with carry) 这条指令与上一条指令类似,只是在两个操作数相加时,要把进位标志C的现行值 加上去,结果送至一个操作数。 指令格式如下: ADC r,src B/W r+src+c?r ADC a,im B/W a+im+c?a ADC dst,im B/W dst+im+c?dst ADC dst,r B/W dst+r+c?dst ADC指令主要用于多字节运算中。在8086中,可以进行8位运算,也可以进行16位运算。但是16位二进制数的表达范围仍然是很有限的,为了扩大数的范围,仍然需要多字节运算。例如,有两个四个字节的数相加,加法要分两次进行,先进行低两个字节相加,然后再做高两个字节相加。在高两个字节相加时要把前两个字节相加以后的进位考虑进去,就要用到带进位的加法指令ADC。 若此两个四字节的数,已经分别放在自FIRST和SECOND开始的存储区中,每个数占四个存储单元,存放时,最低字节在地址最低处,则可以采用以下程序段实现相加操作: MOV AX,FIRST MOV AX,SECOND MOV THIRD,AX MOV AX,FIRST+2 MOV AX,SECOND+2 MOV THIRD+2,AX 这条指令对标志位的影响与ADD相同。 ADC指令的使用举例,如下: ADC操作数 ADC码举例 寄存器,寄存器 ADC AX,SI 寄存器,存储器 ADD BX,TETA[SI] 存储器,寄存器 ADD ALPHA,DI 寄存器,立即数 ADD BX,256 存储器,立即数 ADD GAMMA,30H 累加器,立即数 ADD AL,5 (3) INC(Increment) 这条指令完成对指定的操作数加1,然后返回此操作数。此指令主要用于在循环程序中修改地址指针和循环次数等。 指令格式如下: INC r W r+1?r INC src B/W sec+1?src 这条指令执行的结果影响标志位A、O、P、S和Z,而对进位标志没有影响。 这条指令的操作数可以是在通用寄存器中,也可以在内存中。 指令的使用距离,如下: INC操作数 INC码举例 16位寄存器 INC CX 8位寄存器 INC BL 存储器 INV ALPHA[DI][BX] (4) AAA(unpacked BCD,ASCII,adjust for addition) 这条指令对在AL中的由两个未组合的十进制操作数相加后的结果进行校正,产生一个未组合的十进制和。 两个未组合的十进制数可以直接用ADD指令相加,但要得到正确的未组合的十进制结果,必须在加法指令以后,紧接着用一条AAA指令来加以校正,于是在AX中就可以得到正确的结果。 所谓未组合的十进制数,就是一个字节中只包含一位十进制数,也即十进制数字的ASCII码的高四位置为0以后所形成的数码。即6为00000110,7为00000111等。当这样的两个数相加(必须有一个在AL后)以后,要在AX中得到正确的仍是未组合的十进制结果,就必须进行调整。因为6+7=13,则应该在AL中的为00000011,而在AH中(若初始值为0)为00000001。但加法是按二进制规则进行的,在未调整前AL中的值为: 00000110 +00000111 00001101 调整的操作为: 若(AL&0FH)>9或标志A=1,则 AL?AL+6 AH?AH+1 A?1 C?A AL?AL&0FH 这条指令对标志A和C有影响,而对O、P、S、Z等标志未定义。 指令的使用举例,如下: AAA操作数 AAA码举例 无操作数 AAA (5) DAA(Deeimal Adjust for Addition) 这条指令能对在AL中的由两个组合的(即一个字节中包含两位十进制数)十进制数相加的结果进行校正,以得到正确的组合的十进制和。 我们可以对两个组合的十进制数,直接用ADD指令(目的操作数在AL中)进行相加,但若要得到正确的组合的十进制结果,则必须在ADD指令之后紧接着用一条DAA指令来加以校正,这样在AL中就可以得到正确的组合的十进制和。 这条指令的校正操作为: 若(AL&0FH)>9或标志A=1,则 AL?AL+6 A?1 若AL>9FH或标志C=1则 AL?AL+60H C?1 此指令影响标志A、C、P、S、Z,而对标志O未作定义。 指令的使用距离,如下: DAA操作数 DAA码举例 无操作数 DAA 下面我们举一个多字节相加的例子。若有两个多字节数NA和NB,每一个是16位十进制数,NA放在以FIRST开始的存储区中,NB放在以SECOND开始的存储区中,都是最低字节在前。相加以后的和放在自THIRD开始的存储区中。十进制数在机器中用BCD码表示,故一个字节可表示两个十进制数,16位十进制数用8个字节表示。因是十进制数相加,加完后要用DAA指令,故每次只能是字节相加,因此,加法要做8次,我们用一个循环程序来完成。在最低字节相加时,可用ADD指令;而后面7次相加都要用ADC指令。因是循环程序,故加法全用ADC指令,则在最低字节相加前,要使进位标志C清0。相加的结果应在AL中(DAA指令只要对在AL中相加的结果进行调整),所以,在程序中要用到三个地址指针,再循环前要设置初值。能实现上述要求的程序段如下: MOV BX,OFFSET FIRST MOV SI,OFFSET SECOND MOV DI,OFFSET THIRD MOV CX,8 CLC AGAIN: MOV AL,[BX] ADC AL,[SI] DAA MOV [DI],AL INC BX INC SI INC DI DEC CX JNC AGAIN HLT 2. 减法指令(SUBTRACTION) 8086有7条减法指令。 (1) SUB OPRD1,OPRD2 这条指令完成两个操作数相减,也即从OPRD1中减去OPRD2,结果放在OPRD1中。 具体地说,可以从累加器中减去立即数;或在寄存器和内存操作数中减去立即数;或在 寄存器中减去寄存器或内存操作数;或从寄存器或内存操作数中减去寄存器操作数等。 指令格式如下: SUB r,src B/W r – src ? r SUB a,im B/W a – im ? a SUB dst,r B/W dst - r?dst SUB dst,im B/W dst - im? dst 这条指令影响标志A、C、O、P、S、Z。 指令的使用举例,如下: SUB操作数 SUB码举例 寄存器,寄存器 SUB CX,BX 寄存器,存储器 SUB DX,MATH_TOTAL[SI] 存储器,寄存器 SUB[BP+2],CL 累加器,立即数 SUB AL,10 寄存器,立即数 SUB SI,5280 存储器,立即数 SUB[BP]BALANCE,1000 (2) SBB(Subtract with Borrow) 这条指令与SUB指令类似,只是在两个操作数相减时,还要减去借位标志C的现行值。 指令格式如下: SUB r,src B/W r – src – c ? r SUB a,im B/W a – im – c ? a SUB dst,r B/W dst – r – c ?dst SUB dst,im B/W dst – im – c ? dst 本指令对标志位A、C、O、P、S和Z都有影响。本指令主要用于多字节操作数的相减。 指令的使用举例,如下: SBB操作数 SBB码举例 寄存器,寄存器 SBB BX,CX 寄存器,存储器 SBB DI,[BX]PAYMENT 存储器,寄存器 SBB BALANCE,AX 累加器,立即数 SBB AX,2 寄存器,立即数 SBB CL,1 存储器,立即数 SBB COUNT[SI],10 (3) DEC(Decrement) 本指令对指定的操作数减1,然后送回此操作数。所用的操作数可以是寄存器r,也可以是内存操作数。 在相减时,把操作数作为一个无符号二进制数来对待。指令执行的结果,影响标志A、O、P、S和Z,但对标志C不影响(即保持此指令以前的值)。 指令的使用举例,如下: DEC操作数 DEC码举例 16位寄存器 DEC AX 8位寄存器 DEC AL 存储器 DEC ARRAY[SI] (4) NEG(Negate) NEG OPRD 这条指令是对操作数取补,也即用零减去操作数,再把结果送回操作数。若在字节操作时对-128,或在字操作时对-32768取补,则操作数没有变化,但溢出标志O置位。 这条指令影响标志A、C、O、P、S和Z。此指令执行的结果,一般总是使标志C=1;除非在操作数为零时才使C=0。 指令的使用举例,如下: NEG操作数 NEG码举例 寄存器 NEG AL 存储器 NEG MULTIPLIER (5) CMP(Compare) 比较指令完成两个操作数相减,使结果反映在标志位上,但并不送回结果。 指令的格式为: CMP r,src r – src CMP a,im a – im CMP dst,r dst – r CMP dst,im dst – im 具体地说,比较指令可以使累加器与立即数、任一通用寄存器或任一内存操作数相比较。例如: CMP AL,100 CMP AX,SI CMP AX,DATA[BX] 也可以使任一通用寄存器与立即数、其他的寄存器或任一内存操作数相比较。例如: CMP BX,04FEH CMP DX,DI CMP CX,COUNT[BP] 也可以使内存操作数与立即数,与任一寄存器相比较。例如: CMP DATA,100 CMP COUNT[SI],AX 比较指令主要用于比较两个数之间的关系,即两者是否相等或两个数中哪一个数大。 在比较指令之后,根据Z标志即可判断两者是否相等。若两者相等,相减以后结果为0,Z标志为1;否则为0。 若两者不等,则可利用比较指令之后的标志位的状态来确定两者的大小。 若在AX和BX中的两个正数,要比较确定它们哪个大,可用比较指令: CMP AX,BX 即作AX – BX 操作,由于这两个数都是正数,显然若AX > BX,则结果为正;若AX < BX,则结果为负。所以,可由比较指令执行后的S标志来确定。若S=0,则AX>BX;若S=1,则AX0,B<0 我们知道结果应该是A>B,且比较的结果应该是正数。但若A=+127,B= - 63 ,比较是执行A – B =A+( - B )= - 127+( - ( - 63 ))=+127+63,则在机器中结果为: 0111 1111 +0011 1111 1011 1110 结果D=1,即S=1表示结果为负,所以,若以S标志来判断则会得出A + 127,超出了它的范围,即产生了一处,因而导致了错误的结论。 因此,在这种情况下,就不能只用S标志来判断数的大小了,而必须同时考虑运算的结果是否有溢出。若结果无溢出,即O=0,则仍为S=0,A?B;S=1,AB。 ? 若A<0,B>0 若A= - 63 ,B= + 127,则显然AB的错误结论。同样,出现这样情况的原因,是由于运算的结果为 – 190 小于8位带符号数所能表示的最小值 – 128 ,产生了溢出。 ? 若A < 0,B < 0 在运算过程中不会产生引出。则可以用S标志来判断两个数的大小。 把以上四种情况概括起来,我们可以得出以下结论: 在没有溢出的情况下,即O=0时,若S=0,则A,B;若S=1,则A,B。 在发生溢出的情况下,即O=1时,若S=1,A,B;若S=0,A,B。 所以,当两个带符号数相比较时,要把标志位S和O结合起来一起考虑,才能判断哪一个数大。即只有在O标志和S标志同时为0或同时为1时,A,B。于是可以把A,B的条件写成: S?O=0。 在8086的转移指令中,考虑到上述情况,有两条用于判断带符号数大小的转移指令。大于的转移指令为JG/JNLE,条件为S?O=0,且Z=0;小于的转移指令为JL/JNGE,条件为S?O=1。 若自BLOCK开始的内存缓冲中,有100个带符号数,要求我们找出其中的最大值并把它存放到MAX单元中。 要解决这个问题,我们可以先把数据块的第一个数取至AX中,然后从第二个存储单元开始,依次与AX中的内容相比较,若AX中的值大,则不作其他操作,接着进行下一次比较;若AX中的值小,则把内存单元的内容送至AX中。这样,经过99次比较,在AX中的必然是数据块中的最大值,再把它存至MAX单元中。 要进行99次比较,当然要编写一个循环程序,在每一次循环中都要用比较指令,然后用转移指令来判别大小。循环开始前要置初值。能满足上述要求的程序段为: MOV BX,OFFSET BLOCK MOV AX,[BX] INC BX INC BX MOV CX,99 AGAIN: CMP AX,[BX] JG NEXT MOV AX,[BX] NEXT: INC BX INC BX DEC CX JNZ AGAIN MOV MAX,AX HLT 比较指令后面通常跟着一个条件转移指令,它检查比较结果和决定程序的转向。 本指令影响标志位A、C、O、P、S和Z。 指令的使用举例,如下: CMP操作数 CMP码举例 寄存器,寄存器 CMP BX,CX 寄存器,存储器 CMP DH,ALPHA 存储器,寄存器 CMP[BP+2],SI 寄存器,立即数 CMP BL,02H 存储器,立即数 CMP[BX]BADAR[DI],3420H 累加器,立即数 CMP AL,00010000B (6) AAS(unpacked BCD,ASCII,adjust for subtraction) 本指令与AAA指令类似,能把在AL中的由两个未组合的十进制数相减的结果进行校正,在AL中产生一个正确的未组合的十进制数的差。 在8086中,允许两个未组合的十进制数想减,但想减后腰得到正确的未组合的十进制数的差,就必须在SUB指令以后,紧跟着用一条AAS指令来加以校正,这样就能在AL中得到正确的两个未组合十进制数的差。 校正的操作为: 若(AL&0FH)>9或标志A=1,则 AL?AL – 6 AH?AH – 1 A?1 C?A AL?AL&0FH 此操作影响标志A和C,但对标志O、P、S和Z未定义。 指令的使用举例,如下: AAS操作数 AAS码举例 无操作数 AAS (7) DAS(Decimal Adjust for Subtraction) 本指令与DAA指令类似,能对在AL中的由两个组合的十进制数相减以后的结果进行校正,以得到正确的组合的十进制数的差。 8086中允许两个组合的十进制数想减,但要得到正确的结果,就必须在SUB指令之后,紧接着用一条DAS指令来加以校正,这样就可以在AL中得到正确的两个组合的十进制的差。 校正的操作为: 若(AL&0FH)>9或标志A=1,则 AL?AL – 6 A?1 若AL>9FH或标志C=1,则 AL?AL – 60H C?1 指令的执行结果,影响标志A、C、P、S和Z,但对标志O未定义。 指令的使用举例,如下: DAS操作数 DAS码举例 无操作数 DAS 3. 乘法指令(MULTIPLICATION) 8086中有三条乘法操作指令。 (1) MUL 本指令完成在AL(字节)或AX(字)中的操作数以及与另一个操作数,两个无符号数的乘法操作。双倍长度的乘积,送回到AL和AH(在两个8位数相乘时),或送回到AX和它的扩展部分DX(在两个字操作数相乘时)。 若结果的高半部分(在字节相乘时为AH,在字相乘时为DX)不为零,则标志C=1,O=1;否则C= 0,O=0。所以标志C=1,O=1,则表示在AH或DX中包括有结果的有效数。 本指令影响标志C和O,而对A、P、S、Z等标志未定义。 相乘时的另一操作数可以是寄存器操作数或内存操作数。 MUL src B AX=AL*src MUL src W DX,AX=AX*src 若要把内存单元FIRST和SECOND这两个字节的内容相乘,成绩放在THIRD和FOURTH单元中买可以用以下程序段: MOV AL,FIRST MUL SECOND MOV THIRD,AX 下面是一个实现两个字(16位)相乘的程序例子(不包括必要的伪指令): MOV AX,M1 MUL M2 MOV P1,AX MOV P2,DX HLT 乘法指令的使用举例如下: MUL操作数 MUL码举例 8位寄存器 MUL BL 16位寄存器 MUL CX 8位存储器 MUL MOUNTH[SI] 16位存储器 MUL BAUD_RATE (2) IMUL(Integer Multiply) 整数乘法指令。这条指令除了是完成两个(一个是AL--若是字节相乘,或AX--若是字相乘)带符号数相乘以外,其他与MUL完全类似。若结果的高半部分(对于节字相乘则为AH,对于字相乘则为DX)不是低半部分的符号扩展,则标志C=1,O=1;否则C=0,O=0。若结果的C=1,O=1,则表示高半部分包含有结果的有效数(不只是符号部分)。 IMUL src B AX=AL*src(符合数) IMUL src W DX,AX=AX*src(符号数) 指令的使用举例,如下: IMUL操作数 IMUL码举例 8位寄存器 IMUL CL 16位寄存器 IMUL BX 8位存储器 IMUL RATE_BYTE 16位存储器 IMUL RATE_WORD[BP][DI] (3) AAM(unpacked BCD,ASCII,adjust for multiply) 这条指令能把在AX中的两个未组合的十进制数相乘的结果进行校正,最后在AX中能得到正确的未组合的十进制数的乘积(即高位在AH中,低位在AL中)。 8086允许两个未组合的十进制数直接相乘,但要得到正确的结果,必须在MUL指令之后紧跟一条AAM指令进行校正,最后可在AX中得到正确的两个未组合的十进制数的乘积。 校正的操作为: AH?AL/0AH(AL被0A除的商?AH) AL?AL%0AH(AL被0A除的余数?AL) 如前所述,开一个为组合的十进制数是一位十进制数。所以当两个未组合的十进制数,例如一个为6即00000110,一个为7即00000111,按照二进制的规则相乘时,成绩的有效数在AL中,其值为00101010,即为用二进制表示的乘积。要在AX中得到勇为组合十进制表示的乘积,则乘积的十位数值(0000 0100)应该在AH中,AL中应该为个位数值(0000 0010),就必须要进行校正操作,上面所规定的校正操作就能得到正确的结果。 此指令影响标志位P、S、Z,但对标志A、C、O未定义。 指令的使用举例,如下: AAM操作数 AAM码举例 无操作数 AAM 4. 除法指令 8086有三条除法指令。另外有两条符号扩展操作,以支持带符号数的除法运算。 (1) DIV 这条无符号数的除法指令,能把在AX和它的扩展部分(若是字节相除则在AH和AL中,若是字相除则在DX和AX中)中的无符号被除数被源操作数除,并且把相除以后的商送至累加器(8位时送至AL,16位时送至AX),余数送至累加器的扩展部分(8位时送至AH,16位时送至DX)。 若除数为0,则在内部会产生一个类型0中断。 此指令执行后对标志位A、C、O、P、S和Z的影响是未定义的。 DIV src B AL=AX/src(无符号数) AH=余数 DIV src W AX=DX,AX/src(无符号数) DX=余数 指令的使用举例,如下 DIV操作数 DIV码举例 8位寄存器 DIV CL 16位寄存器 DIV BX 8位存储器 DIV ALPHA 16位存储器 DIV TABLE[SI] (2) IDIV(Integer division) 这条指令除了是完成带符号数相除以外,与DIV指令完全类似。 在字节相除时,最大的商为+127(7FH),而最小的负数商为-127(81H);在字相除时,最大的商为+32767(7FFFH),最小的负数商为-32767(8001H)。相除以后,若商是正的并且超过了上述的最大值,或者商是负的并且小于上述的最小值,则与被0除一样,在内部产生一个类型0中断。 除法操作完成以后,对标志位A、C、O、P、S和Z的影响是未定义的。 指令的使用举例,如下: IDIV操作数 IDIV码举例 8位寄存器 IDIV BL 16位寄存器 IDIV CX 8位存储器 IDIV DIVISOR_BYTE[SI] 16位存储器 IDIV[BX]DIVISOR_WORD (3) AAD(unpacked BCD,ASCII,adjust for division) 这条指令能把在AX中的两位未组合的十进制数在两个数相除以前进行校正,这样在两个未组合的十进制数相除以后可以得到正确的未组合的十进制结果。 例如,在AX中的被除数为62,按照未组合的十进制数表示为: AH AL 00000110 00000010 除数为8,即为00001000,在相除之前必须先校正,使被除数62以二进制形式集中在AL中,即应该校正为: AH AL 00000000 00111110 再用二进制除法指令DIV想除,相除以后,未组合十进制表示的商在AL中,而相应的余数在AH中。所以校正的操作为: AL?AH*0AH+AL AH?0 8086允许两个未组合的十进制数直接相除,但要得到正确的未组合十进制商和余数,则在相除之前,先用一条ADD指令,然后再用一条DIV指令,则相除以后的商送至AL中,而余数送至AH中。AH和AL中的高半字节全为0。 这条指令影响标志位P、S、Z,而对标志A、C、O的影响未定义。 指令的使用举例,如下: AAD操作数 AAD码举例 无操作数 AAD (4) CBW(Convert Byte to Word) 这条指令能扩展在寄存器AL中的字节的符号,把它送至AH中。 若AL,80H,则扩展以后AH?0; 若AL?80H,则扩展以后AH?FFH。 这条指令能在两个字节相除以前,产生一个双位长度的被除数。此指令不影响标志位。 指令系统的使用举例,如下: CBW操作数 CBW码举例 无操作数 CBW (5) CWD(Convert Word to Douable Word) 这条指令能把在AX中的字的符号扩展送至寄存器DX中。 若AX,8000,则DX?0;否则DX?FFFFH。这条指令不影响标志位。 本指令能在两个字相除以前,把在AX中的字的符号扩展至DX中,形成双倍长度的被除数,从而能完成相应的除法。 指令的使用举例,如下: CWD操作数 CWD码举例 无操作数 CWD 若在内存的数据段中,有一个缓冲区,前两个字节是一个16位带符号的被除数,第二、三字节是一个16位带符号的除数。接下来的两个字节存放商,再下来的两个字节存放余数。能实现除法运算的程序为: LEA BX,BUFFER MOV AX,[BX] CWD IDIV 2[BX] MOV 4[BX],AX MOV 6[BX],DX 3.3.3 逻辑运算类 8086可以对8位或16位操作数进行逻辑操作。逻辑操作可以分为两类:单操作数操作和两个操作数操作,下面分别加以介绍: 1.单操作数操作(SINGLE OPERAND OPERATION) 8086提供以下的单操作数逻辑操作指令: (1) NOT 这条指令对源操作数求反,然后送回源操作数。 源操作数可以是寄存器操作数,也可以是存储器操作数。 NOT src B/W src的反码?src 此指令对标志位没有影响。 指令的使用举例,如下: NOT操作数 NOT码举例 寄存器 NOT AX 存储器 NOT CHARACTER (2) 8086有四条移位指令 SAL(Shift Arithmetic Left)算术左移指令; SHL(Shift Logic Left)逻辑左移指令; SAR(Shift Arithmetic Right)算术右移指令; SHR(Shift Logic Right)逻辑右移指令。 这些指令都可以对寄存器操作数或内存操作数进行指定的次数的移位,可以进行字节操作,也可以进行字操作。 这些指令可以一次只移一位,也可以移位由寄存器CL中的内容规定的次数(位数)。 SAL和SHL这两条左移指令,在物理上是完全相同的,每移位一次在右面补0,而最高位进入标志位C。如图: 在移位次数为1的情况下,若移位完了以后,(EA)的最高位与标志位C不相等,则溢出标志O=1;否则O=0。这用以表示移位以后的符号位与移位前的是否相同(若相同,则O=0)。标志位 P、S、Z表示移位以后的结果,标志A未定义。 两条左移指令的使用举例,如下: SAL/SHL操作数 SAL/SHL码举例 寄存器,1 SAL AH,1 寄存器,CL SHL DI,CL 存储器,1 SHL [BX]OVERDRAW,1 存储器,CL SAL STORE_COUNT,CL SAR每执行一次,使操作数右移一位,但保持符号位不变,最低位移至标志C。如图所示。 SAR可以移位指定的次数。指令影响标志位C、O、P、S和Z,但标志A未定义。 算术右移指令的使用举例,如下: SAR操作数 SAR码举例 寄存器,1 SAR DX,1 寄存器,CL SAR DI,CL 存储器,1 SAR N_BLOCKS,1 存储器,CL SAR N_BLOCK,CL SHR每执行一次,使操作数右移一位,最低位进入标志C,最左面补0。如图所示。 指令可以执行指定的次数。在指定的移位次数为1时,若移位以后,操作数的最高位与次高位不同,则标志O=1,反之O=0。这用以表示移位以后的符号位是否改变(O=0,符号位未变)。 逻辑右移指令的使用举例,如下: SHR操作数 SHR码举例 寄存器,1 SHR SI,1 寄存器,CL SHR SI,CL 存储器,1 SHR ID BYTE[SI][BX],1 存储器,CL SHR INPUT_WORD,CL (3) 8086有四条循环指令 ROL(Rotate Left)循环左移指令; ROR(Rotate Right)循环右移指令; RCL(Rotate through CF Left)带进位C循环左移指令; RCR(Rotate through CF Right)带进位C循环右移指令。 前两条循环指令,未把标志位C包含在循环的环中;后两条把标志位C包含在循环的环中,作为整个循环的一部分。 循环指令可以对字节进行操作,也可以对字进行操作。操作数可以是寄存器操作数,也可以是内存操作数。可以是循环移位一位,也可以循环由CL的内容所决定的次数。 ROL指令,每执行一次,把最高位一方面移入标志位C,另一方面返回操作数的最低位,如下图(a)所示。 当规定的循环次数为1时,若循环以后的操作数的最高位不等于标志位C,则溢出标志O=1;否则O=0。这可以用来表示移位前后的符号位是否改变(O=0,则表示符号未变)。 ROL指令只影响标志位C和O。 ROL指令的使用举例,如下: ROL操作数 ROL码举例 寄存器,1 ROL BX,1 寄存器,CL ROL DI,CL 存储器,1 ROL FLAG_BYTE[DI],1 存储器,CL ROL ALPHA,CL ROR指令,每执行一次,操作数的最低位一方面传送至标志C,另一方面循环回操作数的最高位,如上图(b)所示。 当规定的循环次数为1时,则循环移位后操作数的最高位与它的次高位不相等,则标志O=1;否则O=0。这可用以指示移位前后的符号位是否改变(O=0,表示符号位未变)。 ROR指令只影响标志C和O。 ROR指令的使用举例,如下: ROR操作数 ROR码举例 寄存器,1 ROR AL,1 寄存器,CL ROR BX,CL 存储器,1 ROR PORT_STARUS,1 存储器,CL ROR CMD_WORD,CL RCL指令是把标志位C包含在循环中的左循环指令。每执行一次,则操作数的最高位传送至标志C,而原标志C中的内容,传送至操作数的最低位,如上图 (c)所示。 只有在规定循环次数为1时,若循环以后的操作数的最高位与标志C不相等时,则标志O=1,否则O=0。这可以用来表示循环以后的符号位与原来的是否相同。 RCL指令只影响标志C和O。 RCL指令的使用举例,如下: RCL操作数 RCL码举例 寄存器,1 RCL CX,1 寄存器,CL RCL AL,CL 存储器,1 RCL ALPHA,1 存储器,CL RCL [BP]PARAM,CL RCR指令是把标志位C包含在循环的环中的右向循环移位指令。每执行一次,标志位C中的原内容传送至操作数的最高位,而操作数的最低位送至标志C,如上图 (d)所示。 只有当规定的循环次数为1时,在循环以后,若操作数的最高位与次高位不相等,则标志O=1;否则O=0。这可以用来表示循环前后的符号位是否相同。 本指令只影响标志C和O。 RCR指令的使用举例,如下: RCR操作数 RCR码举例 寄存器,1 RCR BX,1 寄存器,CL RCR BL,CL 存储器,1 RCR [BX]STATUS,1 存储器,CL RCR ARRAY[DI],CL 左移一位,只要左移以后的数未超出一个字节或一个字的表达范围,则原数的每一位的权增加了一倍,相当于原数乘以2。 右移一位就相当于除以2。 在书的输入输出过程中,乘以10的操作是经常要进行的。在8086中有乘法指令,乘以10可以采用乘法指令来完成。也可以采用移位和相加的办法来实现。可以采用以下程序段实现x*10运算: SAL AL,1 ; x*2 MOV BL,AL ; 移至BL中暂存 SAL AL,1 ; x*4 SAL AL,1 ; x*8 ADD AL,BL ; x*10 这样,与用乘法指令相比,从指令的数量来说是多了,但是执行时间却要短的多。 x*2运算,也可以用x+x来实现。所以x*10也可以用以下程序段实现: ADD AL,AL ; x*2 MOV BL,AL ; ADD AL,AL ; x*4 ADD AL,AL ; x*8 ADD AL,BL ; x*10 与移位相比,指令数一样,但执行时间长了一些。所以,采用移位的方法实现乘以10的操作是比较合适的。 在8086中可以实现16位数的移位,但是若有一个四字节数,它们或是放在两个通用寄存器中(例如AX和DX中),或是存放在连续的内存单元中。若我们要求这个四字节数整个左移一位或整个右移一位又如何实现呢, 拿左移来说,可以先使低16位左移一位;再把高16位左移一位,其中的困难在于如何把低16位中的最高位D位移至高16位的最低位即D位。任何一条左移指令都1516 可以把D位移至进位标志C中,而要把C中的内容移至最低位可以采用大循环(包括15 C在内的)循环指令。即可用以下指令: SAL AX,1 RCL DX,1 或 SAL FIRST_WORD,1 RCL SECOND_WORD,1 2. 两个操作数操作(TWO OPERAND OPERATION) 8086提供了四条两个操作数的逻辑操作指令。在这些指令操作时,标志C和O复位,而标志S、P、Z反映操作的结果。 (1) AND 这条指令对两个操作数进行按位的逻辑“与”运算。即只有相“与”的两位全为1,“与”的结果才为1;否则“与”的结果为0。“与”运算以后的结果送至目的操作数。 8086的AND指令可以进行字节操作,也可以进行字操作。 “与”指令的一般格式为: AND OPRD1,OPRD2 其中,目的操作数OPRD1可以是累加器,可以是任一通用寄存器,也可以是内存操作数(可用所有寻址方式)。源操作数OPRD2可以是立即数、寄存器,也可以是内存操作数(可用所有寻址方式)。 例如: AND AL,0FH AND AX,BX AND SI,BP AND AX,DATA_WORD AND DX,BUFFER[SI+BX] AND DATA_WORD,00FH AND BLOCK[BP+DI],CX 例如:要把数码0~9的ASCII码转换为相应的二进制数,则可以用“与”指令,是高4位全变成0,而低4位保留,即与0FH想“与”。 摸一个操作数,自己和自己想“与”,操作数不变,但是可以使进位标志C清0 “与”操作指令主要用在使一个操作数中的若干位维持不变,而若干位清为0的场合。这时要维持不变的这些位与“1”相“与”;而要清为0的这些位与“0”相“与”。 此指令执行以后,标志C=0,O=0,标志P、S、Z反映操作的结果;对标志A未定义。 AND指令的使用举例,如下: AND操作数 AND码举例 寄存器,寄存器 AND AL,BL 寄存器,存储器 AND CX,FLAG_WORD 存储器,寄存器 AND ASCII[DI],AL 寄存器,立即数 AND CX,0F0H 存储器,立即数 AND BETA,01H 累加器,立即数 AND AX,01010000B (2) TEST 本指令完成AND指令同样的操作,结果反映在标志位上,但并不送回至目标操作数, 即TEST指令不改变操作数的值。 这条指令通常是用于检测一些条件是否满足,但又不希望改变原有的操作数的情况下。通常在这条指令后面加上一个条件转移指令。 若要检测AL中最低位是否为1,若为1则转移,可用下面指令: TEST AL,01H JNZ THERE : THERE 若要检测AX中的最高位是否为1,若为1则转移,可用下面指令: TEST AX,8000H JNZ THERE : THERE 又若要检测CX中的内容是否为0,若为0则转移,可用下面的指令: TEST CX,0FFFFH JZ : THERE TEST指令的使用举例,如下: TEST操作数 TEST码举例 寄存器,寄存器 TEST SI,DI 寄存器,存储器 TEST SI,END_COUNT 存储器,寄存器 TEST [BX],AX 寄存器,立即数 TEST BX,0CC4H 存储器,立即数 TEST RETURN_CODE,01H (3) OR 对指定的两个操作数进行逻辑“或”运算,即进行“或”运算的两位中的任一个为1(或两个都为1),则或的结果为1;否则为0。或运算的结果送回目的操作数。8086允许对字节或字进行“或”运算。“或”运算指令使标志位C=0,O=0;“或”操作以后的结果反映在标志位P、S和Z上;对标志A未定义。 “或”指令的一般格式为: OR OPRD1, OPRD2 其中,目的操作数OPRD1,可以是累加器,可以是任一通用寄存器,也可以是一个内存操作数(可用所有寻址方式)。源操作数OPRD2,可以是立即数,可以是寄存器,也可以是内存操作数(可用所有寻址方式)。 例如: OR AL,30H OR AX,00FFH OR BX,SI OR DX,DATA_WORD OR BUFFER[BX],SI OR BUFFER[BX+SI],8000H 一个操作数自身相“或”,不改变操作数的值,但是可以使进行标志C请0。 “或”运算主要应用于:如果要求使一个操作数中的若干位维持不变,而另外若干位置为1的场合。这时,要维持不变的这些位与“0”相“或”;而要置为“1”的这些位与“1”相“或”。利用“或”运算,可以对两个操作数进行组合,也可以令某些位置位。 若用一个字节表示一个字符的ASCII码,则最高位(位7)通常为0,。在数据传送,特别是远距离传送时,为了可靠传送常数要进行校检,对一个字符常用的校检方法为奇偶校检,即把字符的ASCII码的最高位用作校检位,是包括校检位在内的一个字符中的为“1”的位的个数恒为奇数——奇校检;或恒为偶数——偶校检。若采用奇校检,则检查字符的ASCII码中为“1”的个数,若以为奇数,则令它的最高位为“0”;否则,令最高位为“1”。若此字符ASCII码已在寄存器AL中,能实现上述校验的程序段为: AND AL,7FH JNP NEXT OR AL,80H NEXT: OR指令的使用举例,如下: OR操作数 OR码举例 寄存器,寄存器 OR AL,BL 寄存器,存储器 OR DX,PORT_ID[DI] 存储器,寄存器 OR FLAG_BYTE,CL 累加器,立即数 OR AL,01101100B 寄存器,立即数 OR CX,01H 存储器,立即数 OR [BX]CMD_WORD,0CFH (4) XOR 这条指令对两个指定的操作数进行“异或”运算。即进行“异或”运算的两位不相同时(即一个为1,另一个为0),“异或”的结果为1;否则为0。异或运算的结果送回一个操作数。 XOR指令的一般格式为: XOR OPRD1,OPRD2 其中,目的操作数OPRD1可以是累加器,可以是任一个通用寄存器,也可以是一个内存操作数(可用全部寻址方式)。源操作数可以是立即数,可以是寄存器,也可以是内存操作数(可用所有寻址方式)。 例如: XOR AL,OFH XOR AX,BX XOR DX,SI XOR CX,COUNT_WORD XOR BUFFER[BX],DI XOR BUFFER[BX+SI],AX 当一个操作数自身做“异或”运算的时候,由于每一位都相同,则“异或”结果必为0,且使进位标志C也为0。这是使操作数的初值清为0的有效方法。如: XOR AX,AX XOR SI,SI 可使AX和SI清0 若要求使一个操作数中的若干位维持不变,而若干位取反,可用“异或”运算来实现。要维持不变的这些位与“0”相“异或”;而要取反的那些位与“1”相“异或”。 XOR指令执行后,标志位C=0,O=0;标志位P、S、Z反映“异或”操作的结果;标志A未定义。 XOR指令的使用举例,如下: XOR操作数 XOR码举例 寄存器,寄存器 XOR CX,BX 寄存器,存储器 XOR CL,MASK_BYTE 存储器,寄存器 XOR ALPHA[SI],DX 寄存器,立即数 XOR AL,01000010B 存储器,立即数 XOR [SI],00C2H 累加器,立即数 XOR AL,0D2H 下面我们通过两个例子,介绍这些逻辑操作指令的作用以及如何使用它们。 例3-1 由ASCII码转换为BCD码。 数字常数在输入输出时,是以十进制形式表示的,而在计算机中却以二进制形式存放。所以输入输出时,就有一个相互转换的问题。 通常在微型计算机中,从键盘输入的十进制数的每一位数码(即0~9中的任一个),是以它的ASCII码表示的;要向CRT输出的十进制数的每一位数码也是用ASCII码表示的。而在机器中的一个十进制数,或者把它转换为相应的二进制数存放,或者以BCD码形式存放。 若在内存的输入缓冲区中,已有若干个用ASCII马表示的十进制数码,则每一个存储单元只存放一位十进制数码。要求把它们转换为响应的BCD码,而把两个相邻存储单元的十进制数码的BCD码合并在一个存储单元中,并且地址高的放在前四位。这样可以节省一般的存储单元。 要把一个十进制数码的ASCII码转换为BCD码,只要把高4位变成0就可以了;要把两位并在一个存储单元中,则只要把地址高的左移四位,再与地址低的组合在一起即可。 在输入缓冲区中,已存放的ASCII码的个数有可能是偶数,但也可能是奇数。若是奇数,则把地址最低的一个转换为BCD码(高4位为0);然后把剩下的偶数个数按统一的方法处理。下面是一个能满足上述要求的汇编语言的程序(不包括伪指令): MOV SI,OFFSET ASCBUF MOV DI,OFFSET BCDBUF MOV CX,COUNT ROR CX,1 JNC NEXT ROL CX,1 MOV AL,[SI] INC SI AND AL,0FH MOV [DI],AL INC DI DEC CX ROR CX,1 NEXT: MOV AL,[SI] INC SI AND AL,0FH MOV BL,AL MOV AL,[SI] INC SI PUSH CX MOV CL,4 SAL AL,CL POP CX ADD AL,BL MOV [DI],AL INC DI LOOP NEXT HLT 例3-2 由BCD码转换成ASCII码 若内存某一缓冲区中,存放着若干个单元的用BCD码表示的十进制数,每一个单元 中放两位BCD码,要求它们分别转换为ASCII码存放在缓冲区中,高4位的BCD码转 换成的ASCII码放在地址较高的单元。 能满足上述要求的一个汇编语言的程序(不包括伪指令)如下: MOV SI,OFFSET BCDBUF MOV DI,OFFSET ASCBUF MOV CX,COUNT CLD TRANT: MOV AL,[SI] INC SI MOV BL,AL AND AL,0FH OR AL,30H MOV [DI],AL INC DI MOV AL,BL INC DI MOV AL,BL PUSH CX MOV CL,4 SHR AL,CL OR AL,30H MOV [DI],AL INC DI POP CX LOOP TRANT HLT 3.3.5 控制转移类 在8086中有四种控制传送指令(Control Transfer Instructions): (1) 调用(Call)、转移(Jump)和返回(Return)指令; (2) 条件传送指令; (3) 重复控制指令; (4) 中断指令。 所有的控制传送操作,使程序在内存的一个新的单元(很可能在一个新的码段区域中) 继续执行。 1. 调用(CALL)、转移(JUMP)和返回(RETURN)指令 8086提供两种基本调用、转移和返回操作。一种是传送控制在现行的码段区域中; 另一种是传送控制到一个任选的码段区域中,而那个区域就变为现行的码段区域。 (1) CALL 本指令是子程序(或过程)的调用指令,在调用结束后,要由所调用的子程序(或过程)中的RET指令,返回CALL指令的下一条指令。为了能保证正确返回,就需要把断点(即CALL指令的下一条指令的地址)入栈保护。 8086允许要调用的子程序(或过程)在现行码段区域中(此时子程序名中包含NEAR),也可以不在现行码段区域中(此时子程序名中包含FAR)。为了保证能正确返回,CALL指令的类型必须与RET指令的类型相匹配。 CALL指令有两种得到目标地址的方法: 直接调用和间接调用。 直接调用(direct CALL),目标地址直接在CALL指令中。 间接调用(indirect CALL),目标地址在由指令指定的寄存器或内存单元中。 对于一个段内的直接调用CALL,堆栈指针SP减2,使IP(指令指针)入栈。从指令中得到的目标过程的相对偏移量(最大为32KB)加到指令指针上。 对于一个段内的间接调用指令,首先SP减2,IP入栈。目标过程的地址偏移量,由指令中指定的16位通用寄存器或存储单元内取出,用它代替IP。 对于交叉段直接CALL指令,SP减2,把现行的码段寄存器CS的内容入栈。CS由指令中包含的段字代替。SP又一次减2,IP入栈,且IP由在指令中的地址偏移量代替。 对于一个交叉段间接CALL指令,SP减2,把现行的CS入栈。CS由指令指定的双字存储器指针的第二个字的内容所代替。SP再次减2,IP入栈,然后IP由指令中指定的双字指针的第一个字的内容所代替。 CALL指令对标志位无影响。 CALL指令的使用举例如下: CALL操作数 CALL码举例 Near proc CALL PROC(段内调用) fat proc CALL FAR_PROC(段内调用) memptrl6 CALL PROC_TABLE[BI] 间接调用 regptrl6 CALL AX remptr32 CALL [BX]TASK[SI] (2) JMP 这是一条无条件转移指令,它无条件地转移控制到目标单元。 JMP指令不像CALL指令,它不要求返回,所以在JMP指令执行过程中,不保留任何信息。 一个段内直接JMP指令,用从JMP指令得到的目标的相对偏移量加到指令指针上来改变指令指针。 若汇编程序能确定目标是在距JMP指令的?127字节之内,就自动产生一个叫做短(SHORT)JMP的两字节指令;否则,它产生一个能在?32K范围内寻址目标的NEAR JMP。 一个段内间接JMP指令,目标地址或是由一个16位通用寄存器,或是由内存单元来寻址。在前一种情况下,IP值取自指令中指定的寄存器;在后一种情况下,IP的值由指令中指定的内存字单元的内容代替。 一个段交叉直接JMP指令,由包含在指令中的值代替CS和IP。 一个段交叉间接JMP指令,由指令指定的双字指针的第一个字单元的内容代替IP,第二个字单元的内容代替CS。 JMP指令对标志位无影响。 JMP指令的使用举例,如下: JMP操作数 JMP码举例 短 --- 标号 JMP SHORT(段内短转移) near --- 标号 JMP WITHIN_SEGMENT(段内转移) far --- 标号 JMP FAR_LABLE(段内转移) menmptrl6 JMP [BX]TARGET 间接转移 regptrl6 JMP CX menmptr32 JMP OTHER SEG[DI] (3) RET 返回指令RET通常作为一个子程序或过程的最后一条指令,用以返回到调用这个子程序的断点处。 一个段内的返回指令,只返回主程序断点处的指令指针值,即把SP所指的堆栈顶部的一个字的内容,弹回到指令指针,且SP加2。 若是一个段交叉返回指令,则要返回主程序断点处的段基地址和指令指针值,则在把SP所指的堆栈顶部的一个字的内容弹回到指令指针外,在SP+2后,继续把SP所指的一个字的内容弹回到码段寄存器CS,SP再次增2。 若在指令中规定了一个任意的POP值,则在上述操作完成以后,RET指令把这个值加到SP上。这个性能可以允许废除一些在执行CALL指令以前入栈的参数(在调用子程序时,往往要求向子程序传递若干参数,这可以在调用子程序前,把这些参数推入堆栈,利用堆栈来传递)。 RET指令对标志位无影响。 RET指令的使用举例,如下: RET操作数 RET码举例 (段内,无POP值) RET (段内,有POP值) RET 4 (段交叉,无POP值) RET (段交叉,有POP值) RET 2 2. 条件转移指令(CONDITIONAL JUMPS) 8086有一连串的条件转移指令,它以某些标志位,或这些标志位的逻辑运算作为依据,若满足指令所规定的条件,则程序转移至指定目标;若不满足条件,则程序顺序执行条件转移指令的下一条指令。这类条件转移的目标地址是采用相对寻址方式,即以转移指令为基准的+127或-128字节的范围之内。这类指令对标志位无影响。 8086中的条件转移指令已经在第2章标志时讨论过,此处不再重复。 3. 重复控制(ITERATION CONTROL) 一个循环程序必须要有指令来控制循环,重复控制指令在循环的头上或尾部确定是否进行循环。是否重复也是有条件的,通常是在CX寄存器中预置循环次数,重复控制指 令,当CX不等于零时,循环至目的地址。若不满足条件(通常当CX=0时),则顺序执行重复控制指令的下一条指令。 重复控制指令的目的地址必须在控制指令的+127和-128字节的范围之内。这些指令对标志位都没有影响。 这些指令对于循环程序和完成串操作是十分有用的。 8086有四种重复控制的指令: (1) LOOP LOOP指令使CX减1,且判断若CX?0,则循环且目标操作数为IP+偏移量(符号扩展到16位)。 要使用LOOP指令,必须把重复次数置于寄存器CX中。 一条LOOP指令相当于以下两种指令的组合: DEC CX JNZ AGAIN LOOP指令的使用举例,如下: LOOP操作数 LOOP码举例 短 –- 标号 LOOP AGAIN (2) LOOPZ/LOOPE 这同一条指令有两种不同的助记符LOOPZ及LOOPE。 此指令使CX-1,且判断只有在CX?0,而且标志Z=1的条件下,才循环至目标操作数--IP+偏移量(符号扩展到16位)。 此指令的使用举例,如下: LOOPZ/LOOPE操作数 LOOPZ/LOOPE码举例 短 –- 标号 LOOPE AGAIN (3) LOOPNZ/LOOPNE 这是同一条指令的两种助记符。此指令使CX-1,且判断只有当CX?0,而且标志Z=0的条件下,才能循环至目标操作数——IP+偏移量(符号扩展到16位)。 此指令的使用举例,如下: LOOPNZ/LOOPNE操作数 LOOPNZ/LOOPNE码举例 短 –- 标号 LOOPNE AGAIN (4) JCXZ(Jump if CX=0) 若CX=0,则传送控制到目标操作数--IP+偏移量(符号扩展到16位)。 这条指令在循环程序的开始处,为了能跳过循环(只要使CX=0)是有用的。 这条指令不影响标志位。 JCXZ指令的使用举例,如下: JCXZ操作数 JCXZ码举例 短 –- 标号 JCXZ COUNT_DONE 4. 中断(INTERRUPT) 在8086中,可以用功能上类似于外部中断的操作来改变程序执行的方向和调用一个类似于子程序的操作,这类操作称为内部中断。 所有的中断操作,把标志寄存器入栈(类似于PUSHF指令),并通过一个中断向量表,实现间接调用(包括段交叉这种类型)。这个中断向量表放在内存的绝对地址0到3FFH单元。表中可有多达256个不同的中断型号的向量,每个型号对应一个四字节的向量。这四个字节中,有两个字节是中断服务程序所在的码段区域基准(将来要送至CS),有两个字节是中断服务程序入口地址的段内偏移量(将来要送至IP)。 8086提供三种中断传送操作指令。 (1) INT n 指令的格式为: INT n (n=0~255) 本指令启动在指令中的中断类型号n所规定的中断过程。 它首先使SP减2,把标志寄存器入栈,此操作与PUSHF指令相同;其次清除标志T和I,以禁止追踪方式和屏蔽中断;然后SP再次减2,把主程序的码段寄存器CS的内容入栈。 用中断类型号n×4来计算向量的地址,把向量的第二个字的内容传送至CS;SP再次减2,把IP内容入栈,然后把上面计算所得的向量地址的第一个字的内容传送至IP,于是控制就转移到中断服务程序。 这样的指令从功能上来说,除了把标志与断点一起入栈和从固定的中断向量表中取出中断服务程序(相当于一个子程序)的入口地址外,与段交叉调用指令是一样的。 系统中最多可用256条这样的中断指令,通常Intel公司和DOS操作系统已经规定了若干低序号的中断指令保留为系统专用,其他的中断序号可由用户在程序中使用。关于中断的详细情况,我们将在第8章中介绍。 若中断指令中的中断类型号为3,这就是已知的断点中断,则汇编程序产生一个以字节指令。 利用这样的软件中断指令,可以要求操作系统给予服务,而且对于每种不同型号的中断,操作系统可以提供一个应用程序。 这种软件中断也可以用来检查外界硬件中断的已经写好的终端服务过程。 本指令使标志位T和I清楚,对其他标志无影响。 INT指令的使用举例,如下: INT操作数 INT码举例 8位立即数(型号=3) INT 3 8位立即数(型号?3) INT 57 (2) INTO(Interrupt on Overflow) INTO指令可以写在一条算术运算指令的后面,若算术运算指令执行的结果产生溢出,即溢出标志O=1,INTO指令检查到标志O=1,则启动一个中断过程;否则,不进行任何操作,接着执行下一个指令。 若标志O=1,INTO指令的操作类似于INT,即先把标志寄存器入栈;清标志T和I;把CS入栈,还要把IP入栈。在入栈过程中,当然要相应地修改堆栈指针SP。 所不同的是,INTO指令规定是中断类型号为4的中断,所以它的中断向量地址为10H。故在CS入栈后,把地址为(4×4+2)=12H的一个字的内容传送至CS;在IP入栈后,把地址为10H的一个字的内容传送至IP。 INTO指令的使用举例,如下: INTO操作数 INTO码举例 无操作数 INTO (3) IRET(Interrupt Return) 所有的中断过程(服务程序)不管是硬件引起的,还是软件引起的,最后一条指令一定是IRET,用以退出中断过程,返回到中断时的断点处。 中断的返回是由于IRET指令把IP、CS和标志位出栈来实现的。由于标志位要恢复中断以前的状态,所以,这样的指令对所有的标志位都有影响。 IRET指令的举例,如下: IRET操作数 IRET码举例 无操作数 IRET 3.3.6 串操作 8086中有一些一字节指令,它们能完成各种基本的字节串或字串(即字节或字的序列)的操作。任一个这样的基本操作,能在指令的前面用一个重复操作前缀使它们重复地操作。 所有基本的串操作指令,用寄存器SI寻址源操作数,并且假定是在现行的数据段区域中(段地址在段寄存器DS中);用寄存器DI寻址目的操作数,并且假定是在现行的附加段区域中(段地址在段寄存器ES中)。 这两个地址指针在每一个串操作以后会自动修改,但按增量还是按减量修改,取决于标志位D。若标志D=0,则在每次操作后,SI和DI增量(字节操作则加1,而字操作则加2);若标志D=1,则每次操作后,SI和DI减量。 任何一个串操作指令,可以在前面加上一个重复操作前缀,于是指令就重复执行,直至在寄存器CX中的操作次数满足要求为止。 重复操作是否完成的检测,是在操作以前进行的。所以若初始化使操作次数为0,它不会引起重复操作。 若基本操作是一个影响Z标志的操作,在重复操作前缀字节中也可以规定与标志Z相比较的值。在基本操作执行以后,Z标志与指定的值不等,则重复终结。 串操作指令的重复前缀应该避免与其他的前缀同时使用。 8086有五种基本的串操作指令。 (1) MOVS(Move String) 把由SI作为指针的源串中的一个字节或字,传送至由DI作为指针的目的串,并且相应地修改指针,以指向串中的下一个元素。 在前面介绍数据传送指令MOV时,我们说过MOV指令不能实现内存单元之间的数据传送,而这种传送要求有时经常会遇到的,这是就要以某一通用寄存器作为桥梁,要实现重复传送,还必须修改地址。而MOVS指令就是为了实现这样的传送而设置的。一条指令,除了直接完成数据从原地址传送至目的地址以外,还自动完成修改地址指针。但MOVS指令中规定源操作数必须用SI寻址,目的操作数必须用DI寻址。 前面的传送100个操作数的例子,可以改为: MOV SI,OFFSET SOURCE MOV DI,OFFSET DEST MOV CX,100 AGAIN: MOVS DEST,SOURCE DEC CX JNZ AGAIN 若采用重复前缀,则可以用一条指令完成整个数据块的传送。但要用重复前缀,数据长度必须放在寄存器CX中。上述程序可以简化为: MOV SI,OFFSET SOURCE MOV DI,OFFSET DEST MOV CX,100 REP MOVS DEST,SOURCE 此指令对标志位无影响。 指令的使用举例,如下: MOVS操作数 MOVS码举例 目的串,源串 MOVE LINE_EDIT,DATA (重复)目的串,源串 REP MOVS SCREEN,BUFFER (2) CMPS(Compare String) 由SI作为指针的源串中与由DI作为指针的目的串(字或字节)相比较(源串-目的串),但相减的结果只反映到标志位上,而不送至任何一个操作数。同时相应地修改源和目的串指针,指向串中的下一个元素。标志位A、C、O、P、S和Z反映了目的串元素和源串元素之间的关系。 这个指令可以用来检查两个串是否相同。通常在此指令之后,应有一个条件转移指令。 下面是一个利用CMPS指令对STRING1和STRING2两个字符串进行比较的程序例子: MOV SI,OFFSET STRING1 MOV DI,OFFSET STRING2 MOV CX,COUNT CLD REPZ CMPSB JNZ UNMAT ;若串不相同,在RESULT单元中置0FFH MOV AL,0 ;若串相等,在RESULT单元中置0 JMP OUTPT UNMAT: MOV AL,0FFH OUTPT: MOV RESULT,AL HLT CMPS指令加上前缀REPE或REPZ,则操作可解释为:“当串未结尾(CX?0)且串相等(Z标志为1)时继续比较”。 若CMPS指令加以前缀REPNE或REPNZ,则操作解释为:“当串未结尾(CX?0)且串不相等(Z标志为0)时继续比较”。 CMPS指令的使用举例,如下: CMPS操作数 CMPS码举例 目的串,源串 CMPS BUFF1,BUFF2 (重复)目的串,源串 REP CMPS ID,KEY (3) SCAS(Scan String) 搜索串指令,关键字放在AL(字节)或AX(字)中,操作时从AL(字节操作)或AX(字操作)的内容中减去由DI作为指针的目的串元素,结果反映在标志位上,但并不改变目的串元素以及累加器中的值。SCAS也修改DI,使指向下一个元素,在标志位A、C、O、P、S和Z中反映了在AL或AX中的搜索值与串元素之间的关系。 利用SCAS指令可以进行搜索,下面我们举一个例子。要把搜索的关键字放在AL(字节)或AX(字)中,用以搜索内存的某一数据块或字符串中,有无此关键字,若有,则把搜索词次数记下来(若次数为0,表示无要搜索的关键字),并且记录下存放关键字的地址。 程序一开始,当然要设置数据块的地址指针(SCAS指令要求设在DI中),要设立数据块的长度(要求设在CX中),把关键字送入AL或AX中。搜索可以用循环程序,或者利用8086中的重复前缀。利用Z标志以判断是否搜索到,一边分别处理。 MOV DI,OFFSET BLOCK MOV CX,COUNT MOV AL,CHAR REPNE SCASB JZ FOUND MOV DI,0 JMP DONE FOUND: DEC DI MOV POINTR,DI MOV BX,OFFSET BLOCK SUB BX,DI MOV DI,BX DONE: HLT 若SCAS指令前加上前缀REPE或REPZ,则操作解释为:“当串未结束(CX?0)且串元素等于搜索值(Z标志=1)时继续搜索”。这种格式可用来搜索从一个给定值的偏离。若SCAS指令前加上前缀REPNE和REPNZ,则操作解释为:“当串未结束(CX?0)且串元素不等于搜索值(Z标志=0)时继续搜索”。这个方式可以用来在一个串中查出一个值。 SCAS指令的使用举例,如下: SCAS操作数 SCAS码举例 目的串 SCAS INPUT_LINE (重读前缀)目的串 REPNE SCAS BUFFER (4) LODS(Load String) 本指令把由SI作为指针的串元素,传送至AL(字节操作)或AX(字操作),同时修改SI使指向串中的下一个元素。这个指令正常情况下是不重复执行的,因为每重复一次,累加器中的内容就要改写,只保留最后一个元素。但是LODS指令在一个软件循环程序中,在用基本的串操作指令构成复杂的串操作时,LODS指令作为其中一部分是十分有用的。 此指令对标志位无影响。 LODS指令的使用举例,如下: LODS操作数 LODS码举例 源串 LODS CUSTOMER_NAME (重复前缀)源串 REP LODS NAME (5) STOS(Store String) 从累加器AL(字节操作)或AX(字操作)传送一个字节或字,到由DI作为指针的目的串中,同时修改DI以指向串中的下一个单元。利用重复操作,可以在串中建立一串相同的值。 此指令对标志位无影响。 STOS指令的使用举例,如下: STOS操作数 STOS码举例 源串 STOS PRONT_LINE (重复前缀)源串 REP STOS DISPLAY 例如:若在内存缓冲区中有一个数据块,起始地址为BLOCK。数据块中的数据有正有负,要求把其中的正负数分开,分别送至同一段的两个缓冲区,存放正数的缓冲区的起始地址为PLUS DATA;存放负数的缓冲区的起始地址为MINUS DATA。 要解决这一问题,可设SI为源数据块的指针,分别设DI和BX为存放正、负数的目的区指针,使用LODS指令,把源数据取至AL中,然后检查其符号位,若是正数,则用STOS指令送至正数缓冲区;若是负数,则可以先把DI与BX交换,然后再用STOS指令送至负数缓冲区。用CX老控制循环次数。程序如下: START: MOV SI,OFFSET BLOCK MOV DI,OFFSET PLUS DATA MOV BX,OFFSET MINUS DATA MOV CX,COUNT GOON: LODS BLOCK TEST AI,80H JNZ MIUS STOSB JMP AGAIN MIUS: XCHG BX,DI STOSB XCHG BX,DI AGAIN: DEG CX JNZ GOON HLT 上述的各种重复操作显然也可以用软件编制一个循环程序完成。 3.3.8 处理控制 标志操作(Flag Operations) 8086有七条直接对单独的标志进行操作的指令。其中,三条是针对进位标志C的,两条是针对标志D的,两条是针对中断标志I的。 (1) CLC(Clear Carry Flag) 此指令使标志C=0。 (2) CMC(Complement Carry Flag) 此指令使标志C取反,即若执行指令前C=0,则此指令使1?C;若C=1,则0?C。 (3) STC(Set Carry Flag) 此指令使标志C=1。 (4) CLD(Clear Direction Flag) 此指令使标志D=0,则在串操作指令时,使地址增量。 (5) STD(Set Direction Flag) 此指令使标志D=1,则在串操作指令时,使地址减量。 (6) CLI(Clear Interrupt Enable Flag) 此指令使中断允许标志I=0。于是在8086系统中,外部装置送至可屏蔽中断INTR引线上的中断请求,CPU就不予以响应即中断屏蔽。但此标志对于非屏蔽中断NMI引线上的请求以及软件中断都没有影响。 (7) STI(Set Interrupt Enable Flag) 此指令使标志I=1,则CPU就可以响应出现在INTR引线上的外部中断请求。 上述的7条标志操作指令,除了对指定的标志进行操作以外,对别的标志都没有影响。 2. 处理器暂停(Processor Halt) 8086的HLT指令使8086进入暂停状态。在暂停状态8086 CPU不进行任何操作,此指令也不影响任何标志。 当8086处在暂停状态时,只有在以下三种情况之一发生时,CPU才能脱离暂停状态: (1) 在RESET线上有复位信号; (2) 在NMI线上有请求; (3) 在中断允许情况下(即标志I=1),在INTR线上有请求。 所以,HLT指令通常是在程序中为了等待中断而使用。 当由中断使处理器脱离暂停状态,在中断返回时,返回至HLT指令的下面一条指令。 3. 处理器脱离(Processor Escape) ESC指令也称为交权(换码)指令,当处理器执行这条指令时把控制权交给协处理器,例如,为了提高系统浮点运算的速度,系统中可以加入数值运算协处理器8087(80x87 FPU),8087的运算指令是与 8086的指令组合在一个指令流中运行的,所有8087运算指令的前面几位,对于8086来说就是一条ESC指令,当执行ESC指令时,8086就 把控制权交给8087,但ESC指令还可以利用8086的寻址方式为8087获取一个存储器操作数。 此指令对标志位无影响。 ESC指令的使用举例,如下: ESC操作数 ESC码举例 立即数,存储数 ESC 6,ARRAY[SI] 立即数,寄存数 ESC 20,AL 4. 处理器等待(Processor Wait) 8086的WAIT指令,在8086的TEST引线无效的条件下,使CPU进入等待状态。在等待状态8086 CPU没有任何操作。 等待状态可以被允许的外部中断源所中断。当中断发生时,入栈保护的IP值就是WAIT指令的地址,所以当中断任务完成返回后,可以重新进入等待状态。 若等待状态结束,执行恢复,则只有在下一条指令执行时,才允许外部中断。 WAIT指令可用于使CPU与外部硬件同步。此指令对标志位无影响。 5. 总线锁定 LOCK是一个一字节的前缀,它可以放在任何指令前面。LOCK这个前缀可以使8086的一条输出引线LOCK有效,这就使在下一条指令执行期间,把总线锁存,使别的主设备不能控制总线。此指令不影响任何标志。 LOCK指令,对于寄存器和存储器内容互换这种情况是十分有用的。
本文档为【计算机理论基础】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_105949
暂无简介~
格式:doc
大小:266KB
软件:Word
页数:95
分类:生活休闲
上传时间:2017-09-28
浏览量:43