目录
第1章概述1
1.180x86系列结构的概要历史1
1.1.1Intel 80862
1.1.2Intel 803862
1.1.3Intel 804863
1.1.4Intel Pentium3
1.1.5Intel P6系列处理器4
1.1.6Intel Pentium Ⅱ4
1.1.7Intel Pentium Ⅲ4
1.1.8Intel Pentium 4处理器4
1.1.9Intel超线程处理器5
1.1.10Intel双核技术处理器6
1.2计算机基础7<p>目录</p> <p>第1章概述1</p> <p>1.180x86系列结构的概要历史1</p> <p>1.1.1Intel 80862</p> <p>1.1.2Intel 803862</p> <p>1.1.3Intel 804863</p> <p>1.1.4Intel Pentium3</p> <p>1.1.5Intel P6系列处理器4</p> <p>1.1.6Intel Pentium Ⅱ4</p> <p>1.1.7Intel Pentium Ⅲ4</p> <p>1.1.8Intel Pentium 4处理器4</p> <p>1.1.9Intel超线程处理器5</p> <p>1.1.10Intel双核技术处理器6</p> <p>1.2计算机基础7</p> <p>1.2.1计算机的基本结构7</p> <p>1.2.2常用的名词术语和二进制编码8</p> <p>1.2.3指令程序和指令系统11</p> <p>1.2.4初级计算机12</p> <p>1.2.5简单程序举例15</p> <p>1.2.6寻址方式19</p> <p>1.3计算机的硬件和软件24</p> <p>1.3.1系统软件24</p> <p>1.3.2应用软件25</p> <p>1.3.3支撑软件25</p> <p>1.4微型计算机的结构25</p> <p>1.4.1微型计算机的外部结构26</p> <p>1.4.2微型计算机的内部结构26</p> <p>1.5多媒体计算机27</p> <p>1.5.1人机接口27</p> <p>1.5.2多媒体计算机的主要功能28</p> <p>1.5.3多媒体计算机的组成28</p> <p>1.6新技术29</p> <p>1.6.1平板电脑29</p> <p>1.6.2大数据和网络存储30</p> <p>1.6.3大数据34</p> <p>1.6.4网格技术34</p> <p>1.6.5云计算36</p> <p>1.6.6物联网37</p> <p>1.6.7人工智能和智能机器人38</p> <p>习题42</p> <p>第2章80x86系列结构微处理器与808645</p> <p>2.180x86系列微处理器是8086的延伸45</p> <p>2.1.18086功能的扩展45</p> <p>2.1.28086性能的提高46</p> <p>2.28086的功能结构47</p> <p>2.38086微处理器的执行环境48</p> <p>2.3.1基本执行环境概要48</p> <p>2.3.2基本的程序执行寄存器49</p> <p>2.3.3存储器组织54</p> <p>习题55</p> <p>第3章8086指令系统57</p> <p>3.1基本数据类型57</p> <p>3.1.1字、双字、四字、双四字的对齐57</p> <p>3.1.2数字数据类型58</p> <p>3.1.3指针数据类型59</p> <p>3.1.4位字段数据类型59</p> <p>3.1.5串数据类型60</p> <p>3.28086的指令格式60</p> <p>3.38086指令的操作数寻址方式60</p> <p>3.3.1立即数61</p> <p>3.3.2寄存器操作数61</p> <p>3.3.3存储器操作数61</p> <p>3.3.4I/O端口寻址64</p> <p>3.48086的通用指令64</p> <p>3.4.1数据传送指令65</p> <p>3.4.2二进制算术指令69</p> <p>3.4.3十进制算术指令78</p> <p>3.4.4逻辑指令80</p> <p>3.4.5移位和循环移位指令85</p> <p>3.4.6控制传送指令87</p> <p>3.4.7串指令94</p> <p>3.4.8标志控制操作98</p> <p>3.4.9段寄存器指令98</p> <p>3.4.10杂项指令98</p> <p>习题99</p> <p>第4章汇编语言程序设计102</p> <p>4.1汇编语言的格式102</p> <p>4.1.18086汇编语言程序的一个例子102</p> <p>4.1.28086汇编语言源程序的格式102</p> <p>4.2语句行的构成103</p> <p>4.2.1标记103</p> <p>4.2.2符号106</p> <p>4.2.3表达式107</p> <p>4.2.4语句110</p> <p>4.3指示性语句110</p> <p>4.3.1符号定义语句111</p> <p>4.3.2数据定义语句111</p> <p>4.3.3段定义语句118</p> <p>4.3.4过程定义语句124</p> <p>4.3.5结束语句125</p> <p>4.4指令语句125</p> <p>4.4.1指令助记符125</p> <p>4.4.2指令前缀126</p> <p>4.4.3操作数寻址方式126</p> <p>4.4.4串操作指令128</p> <p>4.5汇编语言程序设计及举例131</p> <p>4.5.1算术运算程序设计131</p> <p>4.5.2分支程序设计133</p> <p>4.5.3循环程序设计134</p> <p>4.5.4字符串处理程序设计136</p> <p>4.5.5码转换程序设计139</p> <p>4.5.6有关I/O的DOS功能调用142</p> <p>4.5.7宏汇编与条件汇编145</p> <p>习题154</p> <p>第5章处理器总线时序和系统总线161</p> <p>5.18086的引脚功能161</p> <p>5.1.18086的两种组态161</p> <p>5.1.28086的引线163</p> <p>5.28086处理器时序165</p> <p>5.2.1时序的基本概念165</p> <p>5.2.28086的典型时序168</p> <p>5.3系统总线172</p> <p>5.3.1概述172</p> <p>5.3.2PC总线177</p> <p>5.3.3ISA总线179</p> <p>5.3.4PCI总线181</p> <p>5.3.5USB总线184</p> <p>习题185</p> <p>第6章存储器187</p> <p>6.1半导体存储器的分类188</p> <p>6.1.1RAM的种类188</p> <p>6.1.2ROM的种类189</p> <p>6.2读写存储器RAM189</p> <p>6.2.1基本存储电路189</p> <p>6.2.2RAM的结构191</p> <p>6.2.3RAM与CPU的连接194</p> <p>6.2.464KB动态RAM存储器198</p> <p>6.3现代RAM205</p> <p>6.3.1内存条的构成205</p> <p>6.3.2扩展数据输出动态随机访问存储器205</p> <p>6.3.3同步动态随机访问存储器206</p> <p>6.3.4突发存取的高速动态随机存储器209</p> <p>6.4只读存储器209</p> <p>6.4.1掩模只读存储器209</p> <p>6.4.2可擦除的可编程序的只读存储器211</p> <p>习题218</p> <p>第7章输入和输出223</p> <p>7.1概述223</p> <p>7.1.1输入输出的寻址方式223</p> <p>7.1.2CPU与I/O设备之间的接口信息224</p> <p>7.1.3CPU的输入输出时序225</p> <p>7.1.4CPU与接口电路间数据传送的形式225</p> <p>7.1.5IBM PC与外设的接口与现代PC的外设接口226</p> <p>7.2CPU与外设数据传送的方式228</p> <p>7.2.1查询传送方式229</p> <p>7.2.2中断传送方式232</p> <p>7.2.3直接数据通道传送方式233</p> <p>7.3DMA控制器Intel 8237/82372235</p> <p>7.3.1主要功能235</p> <p>7.3.28237的结构236</p> <p>7.3.38237的工作周期237</p> <p>7.3.48237的引线238</p> <p>7.3.58237的工作方式240</p> <p>7.3.68237的寄存器组和编程241</p> <p>习题248</p> <p>第8章中断250</p> <p>8.1引言250</p> <p>8.1.1为什么要用中断250</p> <p>8.1.2中断源250</p> <p>8.1.3中断系统的功能251</p> <p>8.2*简单的中断情况251</p> <p>8.2.1CPU响应中断的条件251</p> <p>8.2.2CPU对中断的响应253</p> <p>8.3中断优先权254</p> <p>8.3.1用软件确定中断优先权255</p> <p>8.3.2硬件优先权排队电路256</p> <p>8.48086的中断方式258</p> <p>8.4.1外部中断258</p> <p>8.4.2内部中断259</p> <p>8.4.3中断向量表259</p> <p>8.4.48086中的中断响应和处理过程259</p> <p>8.5中断控制器Intel 8259A261</p> <p>8.5.18259A的功能261</p> <p>8.5.28259A的结构262</p> <p>8.5.38259A的引线262</p> <p>8.5.48259A的中断顺序264</p> <p>8.5.58259A的编程264</p> <p>8.5.68259A的工作方式269</p> <p>8.6IBM PC/XT的中断结构273</p> <p>8.6.1中断类型273</p> <p>8.6.2IBM PC/XT中系统保留的中断273</p> <p>习题275</p> <p>第9章计数器和定时器电路Intel 8253/8254PIT277</p> <p>9.1概述277</p> <p>9.1.18253PIT的主要功能277</p> <p>9.1.28253PIT的内部结构277</p> <p>9.1.38253PIT的引线279</p> <p>9.28253PIT的控制字280</p> <p>9.38253PIT的工作方式281</p> <p>9.3.1方式0——计完*后一个数时中断281</p> <p>9.3.28253PIT工作方式小结282</p> <p>9.48253PIT的编程284</p> <p>9.5Intel 8254PIT285</p> <p>习题286</p> <p>第10章并行接口芯片289</p> <p>10.1可编程的并行输入输出接口芯片Intel 825**5的结构289</p> <p>10.2方式选择291</p> <p>10.2.1方式选择控制字292</p> <p>10.2.2方式选择举例292</p> <p>10.2.3按位置位/复位功能295</p> <p>10.3方式0的功能295</p> <p>10.3.1方式0的基本功能295</p> <p>10.3.2方式0的时序296</p> <p>10.4方式1的功能297</p> <p>10.4.1方式1的主要功能297</p> <p>10.4.2方式1输入297</p> <p>10.4.3方式1输出299</p> <p>10.5方式2的功能300</p> <p>10.5.1方式2的主要功能300</p> <p>10.5.2方式2的时序301</p> <p>10.5.3方式2的控制字302</p> <p>10.6Intel 825**应用举例303</p> <p>习题305</p> <p>第11章串行通信及接口电路307</p> <p>11.1串行通信307</p> <p>11.1.1概述307</p> <p>11.1.2串行接口标准EIA RS232C接口311</p> <p>11.2Intel 8251A可编程通信接口313</p> <p>11.2.1Intel 8251的基本功能313</p> <p>11.2.2Intel 8251的框图313</p> <p>11.2.3Intel 8251的接口信号315</p> <p>11.2.4Intel 8251的编程317</p> <p>11.2.5Intel 8251应用举例319</p> <p>习题322</p> <p>第12章数模转换与模数转换接口324</p> <p>12.1D/A转换器接口324</p> <p>12.1.1CPU与8位D/A芯片的接口324</p> <p>12.1.28位CPU与12位D/A转换器的接口325</p> <p>12.2A/D转换器接口329</p> <p>12.2.1概述329</p> <p>12.2.2用软件实现A/D转换329</p> <p>12.2.3A/D转换芯片介绍332</p> <p>12.2.4A/D转换芯片与CPU的接口340</p> <p>12.2.5D/A和A/D转换应用举例345</p> <p>习题348</p> <p>第13章x86系列微处理器的结构与工作方式349</p> <p>13.1x86系列处理器的功能结构349</p> <p>13.1.1Intel 8086的功能结构349</p> <p>13.1.2Intel 80386的功能结构349</p> <p>13.1.3Intel 80486的功能结构350</p> <p>13.280x87 FPU的结构353</p> <p>13.2.1概述353</p> <p>13.2.280x87 FPU的数字系统355</p> <p>13.2.380x87 FPU的结构359</p> <p>13.3x86系列结构微处理器的工作方式371</p> <p>13.3.1实地址方式371</p> <p>13.3.2保护虚地址方式372</p> <p>13.3.3虚拟8086方式390</p> <p>13.3.4x86系列结构微处理器中的中断和异常397</p> <p>习题402</p> <p>第14章x86系列微处理器的发展403</p> <p>14.1AMD x8664处理器403</p> <p>14.1.1引言403</p> <p>14.1.2操作模式407</p> <p>14.2Intel Itanium处理器409</p> <p>14.2.1Intel Itanium 体系结构介绍409</p> <p>14.2.2执行环境414</p> <p>14.3x86系列的嵌入式处理器419</p> <p>14.3.1通用描述420</p> <p>14.3.2体系结构概要420</p> <p>习题426</p> <p>附录AASCII(美国信息交换标准码)字符表(7位码)427</p> <p>附录B8088指令系统表428</p> <p>参考文献439</p>显示全部信息前 言前言
本书的**版是在1985年出版的。从计算机技术的发展来看,20世纪80年代,微处理器、微型计算机进入飞速发展时期。1981年,当时计算机界的巨头——IBM公司推出了**代微型计算机IBMPC,它是以Intel公司研制的Intel 8088作为CPU的8位个人计算机(PC),IBMPC的问世极大地推动了个人计算机的迅猛发展。
1984年正值我国改革开放,工业、农业、科学技术飞速发展之际。当时**号召学习、推广和发展微型计算机技术及应用。在这样的背景下,我们编写了本书,为当时我国科技界学习和推广微型计算机做出了一定的贡献。
本书第二版是在1990年出版的。当时微处理器和微型计算机已经有了巨大的发展。微处理器已由8088、8086、80286发展到80386,由16位机发展到32位机,性能和功能也都有了崭新的发展和提升。以0520系列为代表的国产微型计算机也有了长足的发展和进步,应用十分广泛。第二版按照适用于我国各类高校和继续教育的要求,以满足学习和推广标准的16位微型计算机原理与应用为目标,做了重大修改。
1998年,根据微型计算机发展的需要和教学的要求,本书再次做了修订,出版了第三版。<p>前言</p> <p>本书的**版是在1985年出版的。从计算机技术的发展来看,20世纪80年代,微处理器、微型计算机进入飞速发展时期。1981年,当时计算机界的巨头——IBM公司推出了**代微型计算机IBMPC,它是以Intel公司研制的Intel 8088作为CPU的8位个人计算机(PC),IBMPC的问世极大地推动了个人计算机的迅猛发展。</p> <p>1984年正值我国改革开放,工业、农业、科学技术飞速发展之际。当时**号召学习、推广和发展微型计算机技术及应用。在这样的背景下,我们编写了本书,为当时我国科技界学习和推广微型计算机做出了一定的贡献。</p> <p>本书第二版是在1990年出版的。当时微处理器和微型计算机已经有了巨大的发展。微处理器已由8088、8086、80286发展到80386,由16位机发展到32位机,性能和功能也都有了崭新的发展和提升。以0520系列为代表的国产微型计算机也有了长足的发展和进步,应用十分广泛。第二版按照适用于我国各类高校和继续教育的要求,以满足学习和推广标准的16位微型计算机原理与应用为目标,做了重大修改。</p> <p>1998年,根据微型计算机发展的需要和教学的要求,本书再次做了修订,出版了第三版。</p> <p>随着网络时代的来临和多媒体信息的数字化,信息量呈爆炸式增长,信息的存储、处理、交换和传输,强烈地要求和促进了微处理器向64位时代过渡。本书也根据需要做了两次修订,前后出版了第四版和第五版。</p> <p>自2007年本书第五版出版以来,微处理器技术、计算机技术、存储技术以及网络技术仍然按照摩尔定律飞速发展。</p> <p>以Intel公司的芯片为例,现在大量使用的第七代酷睿处理器,就是以更高的频率、更多的核、更多的线程、更多的高速缓存来提高并行处理能力,以满足应用的需要。目前,台式计算机和移动设备能够以更快的速度启动、更长的时间工作,并且以支持高分辨率图形与视频为发展方向。第七代智能Intel酷睿处理器就是为满足这些需要而研制开发的,它以****的方式为用户带来了身临其境般的逼真游戏娱乐感受。无论是在速度方面,还是在灵活性方面,这一代智能处理器都远胜于前代产品。</p> <p>Intel酷睿处理器有4个系列,分别为i3系列、i5系列、i7系列和i9系列。它们的主要特点和应用领域如下。</p> <p>(1) Intel酷睿 i37100处理器: 2个内核,4个线程,3.9GHz基本频率,该处理器快速充电、**续航、内置移动性,主要应用于处理日常任务的PC。</p> <p>(2) Intel酷睿i57500处理器: 4个内核,4个线程,3.40GHz基本频率,该处理器可以快速启动、按需加速,主要应用于家用与商用PC,其4K图形呈现效果能够展示生动的视频与游戏画面。</p> <p>(3) Intel酷睿 i77820X处理器: 8个内核,16个线程,3.60GHz基本频率。具有出众的高速与非凡的性能,主要应用于下一代台式计算机、笔记本电脑及二合一PC,以及高端游戏、多任务处理及内容创作。</p> <p>(4) Intel酷睿 i97900处理器: 10个内核,20个线程,3.30GHz基本频率。主要应用于高性能台式机、**18核处理器,以及**游戏、**任务、高端内容创作。</p> <p>与5年前的PC相比,现在的PC多任务处理速度提升了65%,能以4K清晰度畅玩Overwatch这类游戏,而且电池续航时间超过10小时。</p> <p>芯片技术、计算机技术以及网络技术应用已经渗透到人们社会生活的各个领域。嵌入式应用(如手机)已经成为人们日常生活中不可缺少的工具。</p> <p>技术的发展和进步要求本书必须修订。本次修订中增加了新技术的内容,对计算机的*新技术及应用做了介绍与说明。本版也改正了前一版中的错误。期望广大读者提出宝贵意见和建议。</p> <p> </p> <p>周明德</p> <p>2018年1月</p>显示全部信息免费在线读第3章8086指令系统〖1〗3.1基本数据类型本节介绍80x86系列处理器定义的数据类型。80x86系列处理器的基本数据类型是字节、字、双字、四字和双四字,如图31所示。图31基本数据类型一个字节是8位,一个字是两个字节(16位),双字是4字节(32位),四字是8字节(64位),双四字是16字节(128位)。四字是在Intel 80486处理器中引入80x86系列结构的,双四字是在具有SSE扩展的处理器(例如Pentium Ⅲ)引入的。图32显示了基本数据类型作为内存中的操作数引用时的字节顺序。低字节(位0~7)占用内存中的*低地址,此地址也是此操作数的地址。图32基本数据类型在内存中的字节顺序3.1.1字、双字、四字、双四字的对齐字、双字和四字在内存中并不需要对齐至自然边界。字、双字和四字的自然边界是偶数编号的地址,对于双字和四字来说,地址要分别能被4和8整除。然而,为改进程序的性能,只要可能,数据结构(特别是堆栈)应在自然边界上对齐。这样做的理由是: 对于不对齐的存储访问,处理器要求做两次存储访问操作,而对于对齐的访问只要做一次存储访问操作。跨越4字节边界的字或双字操作数或跨越8字节边界的操作数被认为是未对齐的,要访问它们需要两个分别的总线周期;起始于奇数地址但不跨越字边界的字被认为是对齐的,仍能在一个总线周期内访问。某些操作双四字的指令要求存储操作数在自然边界上对齐。对于双四字的自然边界是能被16整除的偶数地址。对于这些指令,若规定了未对齐的操作数,则会产生通用保护异常(#GP)。有些操作双四字操作数的指令,允许操作数不对齐,但要求额外的总线访问周期。3.1.2数字数据类型虽然字节、字和双字是80x86系列结构的基本数据类型,但某些指令对这些数据类型的附加解释允许在数字数据类型(带符号或无符号的整数)上���作。这些数字数据类型如图33所示。这里以整数类型为例具体介绍。图33数字数据类型80x86系列结构定义了两种类型整数: 无符号整数和符号整数。无符号整数是原始二进制值,范围从0到所选择的操作数尺寸能编码的*大正数。符号整数是2的补码二进制值,能用于表示正的和负的整数值。某些整数指令(例如ADD、SUB、PADDB和PSUBB)可在无符号或符号整数上操作,而一些整数指令(例如IMUL、MUL、IDIV、DIV、FIADD和FISUB)只能在一种整数类型上操作。(1) 无符号整数无符号整数是包含字节、字、双字中的无符号的二进制数。它们的值的范围,对于字节是0~255,对于字是0~65 535,对于双字是0~232-1。无符号整数有时被作为原始数引用。(2) 符号整数符号整数是保存在字节、字、双字中的带符号的二进制数。对于符号整数的所有操作都假定用2的补码表示。符号位定位在操作数的*高位,符号整数编码如表31所示。表31符号整数编码类别2的补码符号正数*大*小0011..1100..01零000..00负*小*大1111..1100..00符号字节整数7位符号字整数15位符号双字整数31位符号四字整数63位负数的符号位为1,正数的符号位为0。整数值的范围,对于字节是-128~ 127,对于字是-32 768~ 32 767,对于双字是-231~ 231-1。当在内存中存储整数值时,字整数存放在两个连续字节中,双字整数存放在四个连续字节中,四字整数存放在8个连续的字节中。3.1.3指针数据类型指针是内存单元的地址(如图34所示)。80x86系列结构定义两种类型的指针: 近(Near)指针(在8086中是16位,在80386以上处理器中为32位)和远(Far)指针(在8086中为32位,在80386以上处理器中为48位)。Near指针是段内的16位偏移量(也称为有效地址)。Near指针在平面存储模式中用于所有存储器引用,或在分段存储模式中用于同一段内的存储器引用。Far指针是一个48位的逻辑地址,包含16位段选择子和32位的偏移。Far指针用于在分段存储模式中的跨段存储引用。在8086中,Near指针在分段存储模式中用于同一段内的存储器引用。Far指针是一个32位的逻辑地址,包含16位段选择子和16位的偏移。Far指针用于在分段存储模式中的跨段存储引用。3.1.4位字段数据类型 一位字段(如图35所示)是连续的位序列。它能在内存中任何字节的任一位位置开始,并能包含多至32位。图34指针数据类型图35字段数据类型3.1.5串数据类型 串是位、字节、字或双字的连续序列。位串能从任一字节的任一位开始并能包含多至232-1位。字节串能包含字节、字或双字,其范围为0~232-1字节(即4GB)。3.28086的指令格式当指令用符号表示时,就是使用8086汇编语言的子集。在此子集中,指令有以下格式: label(标号): mnemonic(助记符)argument1(参数1),argument2(参数2),argument3(参数3)其中: ● label(标号)是一标识符后面跟有冒号(: )。● mnemonic(助记符)是一类具有相同功能的指令操作码的保留名。● 操作数argument1(参数1)、argument2(参数2)和argument3(参数3)是任选的。可以有0~3个操作数,取决于操作码。若存在,它们可能是文字或数据项的标识符、操作数标识符、寄存器的保留名,或者是在程序的另一部分中声明的赋予数据项的标识符。当在算术和逻辑指令中存在两个操作数时,右边的操作数是源,左边的操作数是目的。例如: LOADREG: MOV AX,SUBTOTAL在此例中,LOADREG是标号,MOV是操作码的助记标识符,AX是目的操作数,而SUBTOTAL是源操作数。这条指令的功能是: 把由SUBTOTAL表示的源操作数传送(MOVE)至AX寄存器。3.38086指令的操作数寻址方式8086机器指令有零个或多个操作数。某些操作数是显式规定的,有的是在指令中隐含的。一个操作数能定位在以下地方之一: ● 指令中(立即数);● 寄存器;● 存储单元;● I/O端口。3.3.1立即数某些指令用包含在指令中的数据作为源操作数。这些操作数称为立即操作数(或简称为立即数)。这种寻址方式如图36所示。图36立即寻址方式图37寄存器寻址例如,以下ADD指令加立即数14至AX寄存器的内容: ADDAX,14所有算术指令(除了DIV和IDIV指令)均允许源操作数是立即数。允许的立即数的*大值随指令改变,但绝不能大于无符号双字整数232。3.3.2寄存器操作数源和目的操作数能在以下寄存器中,具体位置取决于正在执行的指令: 图38内存操作数地址● 16位通用寄存器(AX、BX、CX、DX、SI、DI、SP或BP)。● 8位通用寄存器(AH、BH、CH、DH、AL、BL、CL或DL)。● 段寄存器(CS、DS、SS、ES、FS和GS)。● FLAGS寄存器。这种寻址方式如图37所示。某些指令(例如DIV和MUL指令)中使用了包含在一对16位寄存器中的双字操作数。寄存器对用冒号分隔。例如DX:AX,DX包含高序位,而AX包含双字操作数的低序位。若干指令(例如PUSHF和POPF指令)用于装入和存储FLAGS寄存器的内容或设置或清除在此寄存器中的不同的位。其他指令(例如Jcc指令)用在FLAGS寄存器中状态标志的状态作为条件码执行分支等操作。3.3.3存储器操作数在内存中的源和目的操作数由段选择子和偏移量引用,如图38所示。段选择子规定包含操作数的段,偏移量(从段的开始至操作数的**个字节的字节数)规定操作数的线性或有效地址。1. 规定段选择子段选择子能隐含或显式规定。规定段选择子的*简单的方法是把段的基地址加载至段寄存器,然后允许处理器根据正在执行的操作类型,隐含地选择寄存器。处理器按照表32中给定的规则自动选择段。表32段寄存器的约定存储器基准的类型约定段基数可修改的段基数逻辑地址取指令CS 无 IP堆栈操作SS 无 SP源串DS CS、ES、SS SI目的串ES 无 DI用BP作为基寄存器SS CS、DS、ES 有效地址通用数据读写DS CS、ES、SS 有效地址当存数据至内存或从内存取数据时,DS 段默认能被超越以允许访问其他段。在汇编程序内,段超越通常用冒号“: ”处理。例如,以下MOV指令将寄存器AX中的值传送至由ES寄存器指向的段,段中的偏移量包含在BX寄存器中: MOVES:\[BX\],AX;以下的默认段选择,不能被超越: ● 必须从代码段取指令。● 在串操作中的目的串必须存储在由ES寄存器指向的数据段。● 推入和弹出操作必须总是引用 SS 段。某些指令要求显式规定一个段选择子。在这些情况中,16位选择子能在内存单元或在16位寄存器中。例如,以下MOV指令将寄存器BX中的段选择子传送至寄存器DS: MOVDS,BX段选择子也能用在内存中的32位Far指针显式规定。此处,在内存中的**个字包含偏移量,而下一个字包含段选择子。2. 规定偏移量内存地址的偏移量部分或者直接作为一个静态值(称为位移量)规定或者由以下一个或多个成员通过计算得到地址: ● 位移量——一个8位或16位值。● 基地址——在通用寄存器中的值。● 索引——在通用寄存器中的值。由这些成员相加的结果称为有效地址。这些成员的每一个都能为正或负(2的补码)。作为基地址或索引的通用寄存器限制如下: ● SP寄存器不能用作索引寄存器。● 当SP或BP寄存器用作为基地址,SS段是默认的段。在所有其他情况下,DS段是默认段。基地址、索引和位移量能用于任何组合中,这些成员中的任一个都可以是空。每一种可能的组合对于程序员在**语言或汇编语言中使用的数据结构都是有用的。对于地址成员的组合,建议使用以下寻址方式。(1) 位移量位移量代表操作数的直接(不计算)偏移。因为位移量是编码在指令中的,地址的这种形式有时称为**或静态地址。这通常用于访问静态分配的标量操作数,如图39所示。(2) 基地址单独一个基地址表示操作数的间接偏移量,因为在基地址寄存器中的值能够改变,它能用于变量和数据结构的动态存储。这种寻址方式如图310所示。图39直接寻址方式示意图图310基地址寄存器间接寻址示意图(3) 基地址 位移量一个基地址寄存器和一个位移量能一起使用,主要是为了两个不同的目的: ● 作为元素的尺寸不是2、4或8字节时的数组的索引——位移量作为到数组开始处的静态偏移,基地址寄存器保持计算的结果,以确定到数组中规定的元素的偏移。● 为访问记录中的一个字段——基地址寄存器保持记录的开始地址,而位移量是字段的静态偏移。这种寻址方式如图311所示。图311基址加位移量寻址方式示意图这种组合的一种重要特殊情况是访问在过程激活记录中的参数。过程激活记录是当过程进入时建立的堆栈帧。此处,BP寄存器是基地址寄存器的*好选择,因为它自动选择堆栈段。(4) 索引 位移量这种地址方式当数组的元素是2、4或8字节时,为索引进入静态数组提供了有效的方法。位移量定位数组的开始,索引寄存器保持所希望的数组元素的下标。(5) 基地址 索引 位移量用两个寄存器一起支持二维数组(位移量保持数组的开始)或记录的数组的若干实体之一(位移是记录中一字段的偏移)。这种寻址方式如图312所示。图312基址、变址加位移量寻址方式示意图3. 汇编程序和编译器寻址方式在机器码级,所选择的位移量、基寄存器、索引寄存器和比例系数是在指令中编码的。所有汇编程序都允许程序员用这些寻址成员的任何允许的组合以寻址操作数。**语言编译程序基于程序员定义的语言结构选择这些成员的适当组合。3.3.4I/O端口寻址处理器支持多至包含65 536个8位I/O端口的I/O地址空间。在I/O地址空间中也可以定义16位和32位的端口。I/O端口可以用立即操作数或在DX寄存器中的值寻址。用立即数寻址,只能用8位立即数,可寻址I/O地址空间的前256个端口;用DX寄存器间接寻址,可寻址全部I/O地址空间。3.48086的通用指令每条指令用它的助记符和描述名给定。当给定两个或多个助记符时(例如JA/JNBE),它们表示同一指令操作码的不同助记符。汇编程序支持若干指令的冗余助记符以使它易于译码,例如JA(若高于条件转移)和JNBE(若不低于或等于条件转移)表示相同条件。通用指令执行基本数据传送、算术、逻辑、程序流程和串操作,这些指令通常用于编写在8086处理器上运行的应用程序和系统软件。它们操作包含在内存、通用寄存器(AX、BX、CX、DX、DI、SI、BP和SP)和FLAGS寄存器中的操作数,它们也操作包含在内存、通用寄存器和段寄存器(CS、DS、SS和ES)中的内存地址。这些指令组包含以下子组: 数据传送、二进制整数算术、十进制算术、逻辑操作、移位和旋转、程序控制、串、标志控制、段寄存器操作和杂项。3.4.1数据传送指令数据传送指令在内存和通用寄存器和段寄存器之间传送数据。它们也执行特殊的操作,例如堆栈访问和数据转换。1. MOV指令MOV指令是*常用的数据传送指令。它的格式是MOVDOPD,SOPD它有两个操作数,左边的是目标操作数(DOPD),右边的是源操作数(SOPD)。它把8位或16位源操作数传送至目的地。它在通用寄存器之间、存储器和通用寄存器或段寄存器之间传送数据,或把立即数传送至通用寄存器。它的使用举例如表33所示。表33MOV指令使用举例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,SEGMENT_BASE寄存器,段寄存器 MOV BP,SS存储器,段寄存器 MOV [BX]SEG_SAVE,CS2. 交换指令XCHGDOPD,SOPD这是一条交换指令,它有两个操作数: DOPD和SOPD,该指令的功能是使两个操作数交换(即指令执行后DOPD中的内容即为指令执行前SOPD的内容,而指令执行后SOPD中的内容则为指令执行前DOPD中的内容)。这条指令的操作数可以是一个字节或一个字。交换能在通用寄存器与累加器之间、通用寄存器之间(通用寄存器可用r表示,SRC表示源操作数)、存储器和累加器之间进行。但段寄存器不能作为一个操作数。以下是有效的指令: XCHGAX,rXCHG r,SRCXCHG AL,CLXCHG AX,DIXCHG AX,BUFFERXCHG BX,DATA\[SI\]3. 堆栈操作指令在介绍堆栈操作指令之前,我们先介绍一下什么是堆栈,以及为什么需要堆栈。在一个实际程序中,有一些操作要执行多次,为了简化程序,把这些要重复执行的操作编为子程序,也常常把一些常用的操作编为标准化、通用化的子程序。所以一个实际程序常分为主程序(Main Program)和若干子程序(Subroutine),在主程序中往往要调用子程序或要处理中断(关于中断我们将在后面详细讨论),这时就要暂停主程序的执行,转去执行子程序(或中断服务程序),则机器必须把主程序中调用子程序指令的下一条指令的地址值保留下来,才能保证当子程序执行完以后能返回主程序继续执行。若第x1条指令为调用子程序指令,则它的下一条指令x2的地址——即PC(在8086中,则为代码段寄存器CS和指令指针IP)的值要保留下来。主程序调用子程序示意图如图313(a)所示。图313调用子程序示意图另外,执行子程序时,通常都要用到内部寄存器,并且执行的结果会影响标志位,所以,也必须把主程序中有关寄存器中的中间结果和标志位的状态保留下来,这就需要有一个保存这些内容的地方。而且,在一个程序中,往往在子程序中还会调用别的子程序,这被称为子程序嵌套或子程序递归(调用自己),子程序嵌套示意图如图313(b)所示。调用子程序时,不仅需要把许多信息保留下来,而且还要保证逐次正确地返回。这就要求后保留的值先取出来,也即数据要按照后进先出(Last In First Out,LIFO)的原则保留。能实现这样要求的部件就是堆栈。在早期的微型计算机中,堆栈是一个CPU的内部寄存器组,容量有限,于是子程序调用和嵌套的重数就有限;目前,微型计算机一般都是把内存的一个区域作为堆栈,所以,实质上堆栈就是一个按照后进先出原则组织的一段内存区域,这样也就要有一个指针(相当于地址)SP来指示堆栈的顶部在哪儿。8086中规定堆栈设置在堆栈段(SS)内,堆栈指针SP始终指向堆栈的顶部,即始终指向*后推入堆栈的信息所在的单元。SP的初值,可由上述的MOV SP,im指令来设定。SP的初值规定了所用堆栈的大小。堆栈操作指令分为两类: 即把信息推入堆栈的指令PUSH和信息由堆栈弹出的指令POP。(1) 入栈指令PUSHDOPD操作数的长度为字或双字,在入栈操作时,把一个字(或双字)从源操作数传送至由SP(ESP)所指向的堆栈的顶部。例如,有: PUSHAXPUSHBX每一个指令分两步执行: 先SP-1→SP,然后把AH(寄存器中的高位字节)送至SP所指的单元;再次使SP-1→SP, 把AL(寄存器中的低位字节)送至SP所指的单元,如图314所示。 图314堆栈操作示意图随着推入内容的增加,堆栈扩展,SP值减小,但每次操作完,SP总是指向堆栈的顶部。堆栈的*大容量,即为SP的初值与SS之间的距离。在子程序调用和中断时,断点地址的入栈保护与上述的PUSH指令的操作相同,但它们是由子程序调用指令或中断响应来完成的。堆栈操作指令可用来保护现场,或临时保存某一个操作数。总之,入栈操作是把一个字(或双��)的源操作数,送至堆栈的顶部,且在数据传送操作的同时,要相应地修改SP,入栈指令执行一次使SP-2→SP。具体的入栈指令如下: PUSH rr是通用寄存器的总称,seg是段寄存器的总称,src是源操作数的总称。 WSP=SP-2,(SP)=rPUSH seg W SP=SP-2,(SP)=segPUSH src W SP=SP-2,(SP)=src即源操作数可以是CPU内部的通用寄存器、段寄存器(除CS以外)和内存操作数(可用各种寻址方式)。(2) 出栈指令POPDOPD把现行SP所指向的堆栈顶部的一个字(或双字),送至指定的目的操作数;同时进行修改堆栈指针的操作,即SP 2→SP。具体的出栈指令如下: POP r W r=(SP),SP=SP 2POP seg W seg=(SP),SP=SP 2POP dst W dst=(SP),SP=SP 2(3) PUSHA 推入通用寄存器至堆栈PUSHA(Push All)推入所有的16位(即8086)的通用寄存器至堆栈。Temp←(SP);Push(AX);Push(CX);Push(DX);Push(BX);Push(Temp);Push(BP);Push(SI);Push(DI);(4) POPA自堆栈弹出至通用寄存器POPA(Pop All)自堆栈弹出至16位通用寄存器。DI←Pop();SI←Pop();BP←Pop();ESP增量2(跳过堆栈的下2个字节)BX←Pop();DX←Pop();CX←Pop();AX←Pop();4. 输入输出指令(1) IN输入指令,允许把一个字节或一个字由一个输入端口(port),传送至AL(若是一个字节)或AX(若是一个字)。一个计算机可以配接许多外部设备,每个外部设备与CPU之间要交换数据、状态信息和控制命令,每一种这样的信息交换都要通过一个端口来进行。系统中的端口的区分也是像在存储器中那样,用地址来区分。端口地址若是由指令中的n所规定,则可寻址port0~port255,共256个端口;端口地址也可包含在寄存器DX中,则允许寻址64K个端口。具体指令如下: INAL,n B AL=\[n\]INAX,n W AX=\[n 1\]\[n\]IHAL,DX B AL=\[DX\]INAX,DX W AX=\[DX 1\]\[DX\](2) OUT输出指令,允许把在AL中的一个字节或在AX中的一个字,传送至一个输出端口。端口寻址方式与IN指令相同。具体的指令如下: OUTn,AL B AL→\[n\]OUTn,AX W AX→\[n\],\[n 1\]OUTDX,AL B AL→\[DX\]OUTDX,AX W AX→\[DX\]\[DX 1\]5. 扩展指令(1) CWD CWD能把在AX中的字的符号扩展至DX中(形成32位操作数)。若AX 8000,则0→DX; 否则FFFFH→DX。这条指令不影响标志位。这条指令能在两个字相除之前,把在AX中的16位被除数的符号扩展至DX中,形成双倍长度的被除数,从而能完成相应的除法。(2) CBW CBW把在寄存器AL中的字节的符号送至AH中(形成16位操作数)。若AL 80H,则扩展后0→AH;若AL =80H,则扩展后FFH→AH。此指令在字节除法之前,把被除数扩展为双倍长度。此指令不影响标志位。3.4.2二进制算术指令算术运算指令提供加、减、乘、除这4种基本的算术操作。这些操作都可用于字节、字或双字的运算。这些操作也都可用于带符号数与无符号数的运算。若是符号数,则用补码表示。1. 加法指令 (1) ADDADD DOPD,SOPD这条指令完成两个操作数相加,结果送至目标操作数,即DOPD←DOPD SOPD。目的操作数可以是累加器、任一通用寄存器以及存储器。指令格式如下: ADD r,src B/W/Dr ← r srcADD a,ima表示累加器,im表示立即数,dst表示目的操作数(各种寻址方式)。 B/W/Da ← a imADD dst,im B/W/Ddst ← im dstADD dst,r B/W/Ddst ← r dst这条指令影响标志AF、CF、OF、PF、SF、ZF。这条指令的使用如表34所示。表34ADD指令使用举例ADD操作数ADD码举例寄存器,寄存器ADD CX,DX寄存器,存储器ADD BX,ALPHA存储器,寄存器ADD TEMP,CL寄存器,立即数ADD CL,2存储器,立即数ADD ALPHA,2累加器,立即数ADD AX,200(2) ADCADC(Add with Carry)指令的格式为: ADCDOPD,SOPD这条指令与上一条类似,只是在两个操作数相加时,要把进位标志C的现行值加上去,结果送至一个目标操作数(DOPD)。如: ADC r,srcr ← r src cADC a,im a ← a im cADC dst,im dst ← dst im cADC dst,r dst ← dst r cADC指令主要用于多字节运算中。在8086中,可以进行8位运算,也可以进行16位运算。但是16位二进制数的表示范围仍然是很有限的,为了扩大数的范围,仍然需要多字节运算。例如,有两个4个字节的数相加,加法要分两次进行,先进行低两字节相加,然后再做高两字节相加。在高两字节相加时要把低两字节相加以后的进位考虑进去,就要用到带进位的加法指令ADC。若此两个四字节的数已分别放在自FIRST和SECOND开始的存储区中,每个数占4个存储单元,存放时,*低字节在地址*低处,则可用以下程序段实现相加操作: MOV AX,FIRSTADD AX,SECONDMOV THIRD,AXMOV AX,FIRST 2ADC AX,SECOND 2MOV THIRD 2,AXADC指令的使用如表35所示。表3**DC指令使用举例ADC操作数ADC码举例寄存器,寄存器ADC AX,SI寄存器,存储器ADC DX,TETA[SI]存储器,寄存器ADC ALPHA[BX][SI],DI寄存器,立即数ADC BX,256存储器,立即数ADC GAMMA,30H累加器,立即数ADC AL,52. 减法指令(1) SUBSUB指令的格式为: SUBDOPD,SOPD这条指令完成两个操作数相减,也即从DOPD中减去SOPD,结果放在DOPD中。具体地说,可以从累加器中减去立即数,或从寄存器或内存操作数中减去立即数,或从寄存器中减去寄存器或内存操作数,或从寄存器或内存操作数中减去寄存器操作数等。如: SUB r,src B/W/D r - src → rSUB a,im B/W/D a - im → aSUB dst,r B/W/D dst - r → dstSUB dst,im B/W/DB dst - im → dst这条指令影响标志AF、CF、OF、PF、SF、ZF。此指令的使用如表36所示。表36SUB指令使用举例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) SBBSBB(SuBtract with Borrow)指令的格式为: SBB DOPD,SOPD这条指令与SUB指令类似,只是在两个操作数相减时,还要减去借位标志CF的现行值。如: SBB r,srcr -src → rSBB a,im a -im → a SBB dst,r dst -r → dstSBB dst,im dst -im → dst本指令对标志位AF、CF、OF、PF、SF和ZF都有影响。本指令主要用于多字节操作数相减时。此指令的使用如表37所示。表37SBB指令使用举例SBB操作数SBB码举例寄存器,寄存器SBB BX,CX寄存器,存储器SBB DI,[BX]PAYMENT存储器,寄存器SBB BALANCE,AX累加器,立即数SBB AX,2寄存器,立即数SBB CL,1存储器,立即数SBB COUNT[SI],103. 乘法指令(1) MUL无符号数乘法指令MUL指令的格式为: MULSOPD本指令完成在AL(字节)或AX(字)中的操作数以及另一个操作数(两个无符号数)的乘法。双倍长度的乘积,送回到AL和AH(在两个8位数相乘时),或送回到AX和它的扩展部分DX(在两个字操作数相乘时)。若结果的高半部分(在字节相乘时为AH,在字相乘时为DX)不为零,则标志CF=1,OF=1;否则CF=0,OF=0。所以标志CF=1,OF=1表示在AH或DX中包含结果的有效数。本指令影响标志CF和OF,而对AF、PF、SF、ZF等未定义。相乘时的另一操作数可以是寄存器操作数或内存操作数。如: MULsrcB AX=AL*srcMULsrcW DX:AX=AX*src若要把内存单元FIRST和SECOND这两个字节的内容相乘,乘积放在THIRD和FOURTH单元中,可以用以下程序段: MOVAL,FIRSTMUL SECONDMOV THIRD,AX此指令的使用如表38所示。表38MUL指令使用举例MUL操作数MUL码举例8位寄存器MUL BL16位寄存器MUL CX8位存储器MUL MONTH[SI]16位存储器MUL BAUD_RATE以上是8086中的无符号数乘法指令,隐含以累加器(字节乘法为AL,字乘法为AX)作为一个操作数,在指令中规定另一操作数,乘法的结果放在累加器(字节相乘结果在AX)或累加器及其延伸部分(字相乘,结果放在DX:AX)中。(2) IMUL符号数乘法指令整数乘法指令。这条指令除了完成两个带符号数相乘以外,其他与MUL完全类似。若结果的高半部分(对于字节相乘则为AH,对于字相乘则为DX)不是低半部分的符号扩展,则标志CF=1,OF=1;否则CF=0,OF=0。若结果的CF=1,OF=1,则表示高半部分包含结果的有效数(不光是符号部分)。IMULsrcB AX=AL*src(符号数)IMULsrcW DX:AX=AX*src(符号数)此指令的使用如表39所示。表39IMUL指令使用举例IMUL操作数IMUL码举例8位寄存器IMUL CL16位寄存器IMUL BX8位存储器IMUL RATE_BYTE16位存储器IMUL RATE_WORD[BP][DI]4. 除法指令(1) DIV这条无符号数的除法指令,能把在AX和它的扩展部分(若是字节相除则在AH和AL中,若是字相除则在DX:AX中)中的无符号被除数被源操作数除,且把相除以后的商送至累加器(8位时送至AL,16位时送至AX),余数送至累加器的扩展部分(8位时送至AH,16位时送至DX)。若除数为0,则在内部会产生一个类型0中断。此指令执行后对标志AF、CF、OF、PF、SF和ZF的影响是未定义的。DIVsrcBAL=AX/src (无符号数) AH=余数DIVsrcW AX=DX:AX/src (无符号数) DX=余数此指令的使用如表310所示。表310DIV指令使用举例DIV操作数DIV码举例8位寄存器DIV CL16位寄存器DIV BX8位存储器DIV ALPHA16位存储器DIV TABLE[SI](2) IDIVIDIV(Integer Division)指令除了完成带符号数相除以外,与DIV完全类似。在字节相除时,*大的商为 127(7FH),而*小的负数商为-127(81H);在字相除时,*大的商为 32 767(7FFFH),*小的负数商为-32 767(8001H)。若相除以后,商是正的且超过了上述的*大值,或商是负的且小于上述的*小值,则与被0除一样,在内部产生一个类型0中断。除法操作完成以后,对标志位AF、CF、OF、PF、SF和ZF的影响是未定义的。此指令的使用如表311所示。表311IDIV指令的使用举例IDIV操作数IDIV码举例8位寄存器IDIV BL16位寄存器IDIV CX8位存储器IDIV DIVISOR_BYTE[SI]16位存储器IDIV [BX]DIVISOR_WORD5. 增量减量指令(1) INCINC指令完成对指定的操作数加1,然后返回此操作数。此指令主要用于在循环程序中修改地址指针和循环次数等。这条指令执行的结果影响标志位AF、OF、PF、SF和ZF,对进位标志没有影响。这条指令的操作数可以是在通用寄存器中,也可以在内存中。INCr W r 1 → rINCsrc B/W src 1 → src此指令的使用如表312所示。表312INC指令使用举例INC操作数INC码举例16位寄存器INC CX8位寄存器INC BL存储器INC ALPHA[DI][BX](2) DECDEC指令对指定的操作数减1,然后把结果送回操作数。所用的操作数可以是寄存器r,也可以是内存操作数。在相减时,把操作数作为一个无符号二进制数来对待。指令执行的结果影响标志AF、OF、PF、SF和ZF,但对标志C没有影响(即保持此指令以前的值)。此指令的使用如表313所示。表313DEC指令使用举例DEC操作数DEC码举例16位寄存器DEC AX8位寄存器DEC AL存储器DEC ARRAY[SI]6. NEG取补指令NEG指令是对操作数取补,也即用零减去操作数,再把结果送回操作数。若在字节操作时对-128,或在字操作时对-32 768取补,则操作数没变化,但溢出标志OF置位。此指令影响标志AF、CF、OF、PF、SF和ZF。此指令执行的结果,一般总是使标志CF=1; 除非在操作数为零时,才使CF=0。此指令的使用如表314所示。表314NEG指令使用举例NEG操作数NEG码举例寄存器NEG AL存储器NEG MULTIPLIER7. CMP比较指令比较指令完成两个操作数相减,使结果反映在标志位上,但两操作数不变。指令的格式为: CMP r,srcr - srcCMP a,im a - imCMP dst,r dst - rCMP dst,im dst - im具体地说,比较指令可使累加器与立即数、任一通用寄存器或任一内存操作数相比较,也可以使任一通用寄存器与立即数、其他寄存器或任一内存操作数相比较,还可以使内存操作数与立即数或任一寄存器相比较。比较指令主要用于比较两个数之间的关系,即两者是否相等,或两个中哪一个大。在比较指令之后,根据ZF标志即可判断两者是否相等,若两者相等,相减以后结果为0,则ZF标志为1;否则为0。若两者不等,则可利用比较指令之后的标志位的状态来确定两者的大小。若在AX和BX中有两个正数,要比较确定它们哪个大,可用比较指令: CMP AX,BX即令执行AX-BX。由于这两个数都是正数,显然若AX>BX,则结果为正;若AXBX;而若SF=1,则AX