项目5 学习指令系统和寻址方式 项目5学习指令系统和寻址方式 计算机系统主要由硬件和软件两部分组成。所谓硬件就是指由CPU、存储器以及外部设备等组成的实际装置。软件则是为便于用户使用计算机而编写的各种程序和数据的集合,它实际上由一系列的机器指令组成。不同的处理器有着不同的指令系统,学习和掌握指令系统的使用对于编程指挥计算机操作至关重要。 指令系统和寻址方式展现的是计算机指令传达体系及快速找到数据或指令的方式。它们的好坏直接关系着计算机运行的速度。从古到今,指令传达的方式不断变化,从狼烟、飞鸽传书,到后来的电台、电话,充分展现了人类的智慧,是人类文明的体现。特别是在抗日战争时期,中国共产党的地下工作者摸索出来的指令传递方式为取得抗日战争的胜利立下了汗马功劳。 这里将重点讨论Intel 8086/8088指令系统及其寻址方式。 视频讲解 知识目标: 指令的分类、周期 指令的寻址方式 指令系统 能力目标: 了解指令系统的概念、分类 理解指令周期、寻址方式及指令系统 掌握数据传送、算术运算、逻辑运算和移位、串操作、控制转移、处理器控制等常见指令的组成、功能和处理方式 素质目标: 提高遵循知识、指令和计划的能力 培养进行明智决策的能力 学习教学: 指令周期; 操作数寻址; 指令寻址 学习难点: 指令周期; 操作数寻址 5.1任务1学习指令系统概述 程序是指令的有序集合,指令是程序的组成元素,通常一条指令对应着一种基本操作。一个计算机能执行什么样的操作,能做多少种操作,是由该计算机的指令系统决定的。一个计算机的指令集合,就是该计算机的指令系统。每种计算机都有自己固有的指令系统,互不兼容。但同一系列的计算机其指令系统是向上兼容的。 每条指令由两部分组成: 操作码字段和地址码字段,其格式如图51所示。 操作码操作数(地址码) 图51指令格式 视频讲解 操作码字段: 用来说明该指令所要完成的操作。 地址码字段: 用来描述该指令的操作对象。一般是直接给出操作数,或者给出操作数存放的寄存器编号,或者给出操作数存放的存储单元的地址或有关地址的信息。 根据地址码字段所给出地址的个数,指令格式可分为零地址、一地址、二地址、三地址、多地址指令。大多数指令需要双操作数,分别称两个操作数为源操作数和目的操作数,指令运算结果存入目的操作数的地址中去。这样,目的操作数的原有数据将被取代。Intel 8086/8088的双操作数运算指令就采用这种二地址指令。 指令中用于确定操作数存放地址的方法,称为寻址方式。如果地址码字段直接给出了操作数,这种寻址方式叫立即寻址; 如果地址码字段指出了操作数所在的寄存器编号,叫寄存器寻址; 如果操作数存放在存储器中,则地址码字段通过各种方式给出存储器地址,叫存储器寻址。 指令有机器指令和汇编指令两种形式。前一种形式由基2码(二进制)组成,它是机器所能直接理解和执行的指令。但这种指令不好记忆,不易理解,难写难读。因此,人们就用一些助记符来代替这种基2码表示的指令,这就形成了汇编指令。汇编指令中的助记符通常用英文单词的缩写来表示,如加法用ADD、减法用SUB、传送用MOV等。这些符号化了的指令使得书写程序、阅读程序、修改程序变得简单方便,但计算机不能直接识别和执行,在把它交付给计算机执行之前,必须翻译成计算机所能识别的机器指令。 注意: 汇编指令与机器指令是一一对应的,所以我们经常说汇编语言比C语言的执行效率要高。本书中的指令都使用汇编指令形式书写,便于学习和理解。 5.2任务2学习指令的分类 1. 数据传送指令 这是一种常用指令,用以实现寄存器与寄存器,寄存器与存储单元以及存储单元与存储单元之间的数据传送,对于寄存器来说,数据传送包括对数据的读(相当于取数指令)和写(相当于存数指令)操作。数据传送时,数据从源地址传到目的地址,而源地址中的数据保持不变。数据传送指令可以一次传送一个数据,也可以一次传送一批数据。有些机器还设置了数据交换指令,这种指令和数据传送指令很相似,所不同的是它完成源操作数与目的操作数的互换,实现双向数据传送。 2. 算术运算指令 算术运算指令包括二进制数的运算及十进制数的运算指令。算术运算指令用来执行加、减、乘、除算术运算,它们有双操作数指令,也有单操作数指令。单操作数指令不允许使用立即寻址方式。乘法和除法指令的目的操作数采用隐含寻址方式,汇编指令只指定源操作数,源操作数不允许使用立即寻址方式。双操作数指令不允许目的操作数为立即寻址,不允许两个操作数同时为存储器寻址。段寄存器只能被传送、压栈、出栈。特别要强调的是,当汇编程序无法确定指令中操作数的长度时,必须用BYTE PTR、WORD PTR、DWORD PTR伪指令来指定操作数的长度。 注意: 不论是双操作数还是单操作数,都不允许使用段寄存器。 3. 逻辑运算指令 一般计算机都具有与、或、非(求反)、异或(按位加)和测试等逻辑运算指令。有些计算机还设置了位操作指令,如位测试、位清除、位求反等指令。 4. 位移指令 位移指令可以实现对操作数左移或右移一位或若干位,按移位方式分为三种: 算术位移指令、逻辑位移指令和循环位移指令。 算术位移的操作数为带符号数,逻辑位移的操作数为无符号数。主要差别在于右移时,填入最高位的数据不同。算术右移保持最高位(符号位)不变,而逻辑右移最高位补0。循环位移按是否与进位位CF一起循环,还分为大循环(与进位位CF一起循环)和小循环(自己循环)两种,一般循环是指小循环,主要用于实现循环式控制、高低字节互换等。算术、逻辑位移指令还可用于实现简单乘除运算。 5. 堆栈操作指令 堆栈是由若干连续储存单元组成的先进后出(FILO)存储区,第一个送入堆栈中的元素存放到栈底,最后送入堆栈的元素存放在栈顶。栈底是固定不变的,栈顶却随着数据的入栈和出栈在不断变化。为了表示栈顶的位置,用一个寄存器指出栈顶的地址,这个寄存器就称为堆栈寄存器SP。 由于堆栈具有先进后出的特性,因而在中断服务程序、子程序调用过程中广泛用于保存返回地址、状态标志及现场信息。另一个重要的作用是在子程序调用时利用堆栈传递数据。首先把所需传递的参数压入堆栈中,然后调用子程序。 6. 字符串处理指令 字符串处理指令是一种非数值处理指令,一般包括字符串传送、字符串转换(把一种编码的字符串转换为另一种编码的字符串)、字符串比较及字符串查找(查找字符串中的某个子串) 7. 其他指令 (1) 输入/输出指令。 计算机本身仅是数据处理和管理机构,不能产生原始数据,也不能长期保存数据。所处理的一切原始数据均来自输入设备,所得的处理结果必须通过外部设备输出。这些工作要使用输入/输出指令。由此可见,输入/输出指令是计算机中很重要的一类指令。 (2) 特权指令。 所谓特权指令是指具有特殊权限的指令,由于这类指令的权限最大,所以如果使用不当,就会破坏系统或其他用户信息。因此为了安全起见,这类指令只能用于操作系统或其他系统软件,而一般不直接提供给用户使用。 一般说来,在单用户、单任务的计算机中不具有也不需要特权指令,而在多用户、多任务的计算机系统中,特权指令却是不可缺少的。它主要用于系统资源的分配和管理,包括改变系统的工作方式,检测用户的访问权限,修改虚拟存储器管理的段表、页表和完成任务的创建与切换等。 (3) 转移指令。 视频讲解 转移指令用来控制程序的执行方向,实现程序的分支。按转移的性质,转移指令分为无条件转移指令和条件转移指令。无条件转移指令不受任何条件约束,直接把控制转移到所指定的目的地,从那里开始执行。而条件转移指令却先测试某些条件,然后根据所测试的条件是否满足来决定转移或不转移。计算机中的CPU设有一个状态寄存器,用来保存最近执行的算术、逻辑运算指令、位移指令等结果标志。 (4) 陷阱与陷阱指令。 陷阱实际上是一种意外中断事故,中断的目的不是为请求CPU的正常处理,而是为了通知CPU出现了故障,并根据故障的情况,转入相应的故障处理程序。 (5) 子程序调用指令。 在编写程序的过程中,常常需要编写一些经常使用的、能够独立完成某一特定功能的程序段,在需要时调用,而不必重复编写,以便节省存储空间和简化程序设计,这就是所谓的子程序。子程序调用指令就是在主程序中调用这些子程序段所使用的指令。它类似无条件转移JMP指令,所不同的是,子程序执行结束是要返回的。 5.3任务3学习指令周期 1. 指令周期的基本概念 计算机之所以能自动地工作是因为CPU能从存放程序的内存中取出一条指令并执行这条指令; 紧接着又取下一条指令,执行下一条指令……,如此周而复始,构成一个封闭的循环。除非遇到停机指令,否则这个循环将一直继续下去。 2. 指令周期的过程 通常将一条指令从取出到执行完毕所需要的时间称为指令周期。对应指令执行的三个阶段,指令周期一般分为: 取指周期、取操作数周期和执行周期三个部分。 (1) 取指周期。 取指周期是取出某条指令所需的时间。 在取指周期中CPU主要完成两个操作: ①按程序计数器PC的内容取指令; ②形成后继指令的地址。 取指周期=(指令的长度/存储字的长度)×主存的读写周期。我们可以用设计指令格式时缩短指令长度、设计主存时增加主存储字字宽和采用快速的主存等措施来缩短取指周期,提高取指的速度。 (2) 取操作数周期。 取操作数周期是为执行指令而取操作数所需的时间。 取操作数周期的长短与操作数的个数有关、与操作数所处的物理位置有关还与操作数的寻址方式有关。取操作数周期中应完成的操作是,计算操作数地址并取出操作数。操作数有效地址的形成由寻址方式确定。 小知识: 寻址方式不同,有效地址获得的方式不同、过程不同,提供操作数的途径也不同。因此操作数周期所进行的操作对不同的寻址方式是不相同的。 视频讲解 (3) 执行周期。 执行周期是完成指令所规定的操作和传送结果所需的时间。 它与指令规定的操作复杂程度有关。例如,一条加法指令与一条乘法指令的指令周期是不同的。执行周期还与目的操作数的物理位置和寻址方式有关。状态信息中的条件码在执行周期中存入程序状态字PSW。若该指令是转移指令,在该周期中还要生成转移地址。 指令周期常常用若干CPU周期表示,CPU周期也称为机器周期。由于CPU内部的操作速度较快,而CPU访问一次内存所花的时间较长,因此通常用内存中读取一个指令字的最短时间来规定CPU周期。每个机器周期又包含若干时钟周期。 一个指令周期包含的机器周期个数也与指令所要求的动作有关,如单操作数指令,只需要一个取操作数周期,而双操作数指令需要两个取操作数周期。实际上,不同的指令可以有不同的机器周期个数,而每个机器周期又可包含不同的时钟脉冲个数。 在CPU的控制中除了有取指周期、取操作数周期、执行周期外,还有中断周期、总线周期及I/O周期。中断周期用于完成现行程序与中断处理程序间的切换,总线周期用于完成总线操作及总线控制权的转移,I/O周期完成输入/输出操作。 小知识: 指令周期中所包含的CPU周期的长度并不是相同的,因此指令周期又分为定长CPU周期组成的指令周期和不定长CPU周期组成的指令周期。 5.4任务4学习寻址方式 寻址方式是指如何在指令中表示一个操作数的地址以及如何确定下一条将要执行的指令地址。前者称为操作数寻址,后者称为指令寻址。寻址方式是指令系统中一个重要的内容,与硬件结构密切相关。尤其对于使用汇编语言编写程序的人来说,了解寻址方式在明确数据的流向以及计算指令的执行时间等方面都是非常重要的。 不同系列的微处理器,其寻址方式不完全相同,但其原理基本上是一样的。本节以8088/8086为例,介绍各种寻址方式。 5.4.1活动1详解操作数寻址 操作数寻址也叫数据寻址,是指寻找和获得操作数或操作数存放地址,是形成操作数有效地址的方法。机器执行指令的目的就是对指定的操作数完成规定的操作,将操作结果存入规定的地方。因此,如何获得操作数的存放地址及操作结果的存放地址就是一个很关键的问题。8088/8086 CPU有多种方法来获取操作数的存放地址及操作结果的存放地址,这些方法统称为数据寻址方式。 操作数及操作结果存放的地点有三处: 存放在指令的地址码字段中; 存放在寄存器中; 存放在存储器的数据段、堆栈段或附加数据段中。与之对应有三种操作数,即立即操作数、寄存器操作数、存储器操作数。寻找这些操作数有三种基本寻址方式,即立即寻址方式、寄存器寻址方式、存储器寻址方式。其中,存储器寻址又包括多种寻址方式。下面分别介绍这些寻址方式。 1. 立即寻址方式 立即寻址方式是指寻找的操作数紧跟在指令操作码之后,也就是说地址码字段存放的不是操作数的地址,而是操作数本身。立即数作为指令的部分存放于代码段中,紧跟在操作码之后,CPU在取指令的同时取出立即数参与运算。立即数可以是一个8位整数,也可以是一个16位整数。 立即寻址方式的特点是: 指令执行的时间很短,因为不需要访问存储器获取操作数,从而节省了访问存储器的时间; 立即寻址方式的使用范围很有限,主要用于给寄存器赋初值。 【例51】MOVAX,67 指令执行后,(AX)=67。 【例52】MOVAL,0FFH 操作的示意图如图52所示。 【例53】MOVAX,1234H 操作的示意图如图53所示。 图528位立即寻址操作示意图 图5316位立即寻址操作示意图 另外要注意,这种寻址方式不能用于单操作数指令; 若用于双操作数指令,也只能用于源操作数字段,不能用于目的操作数字段。 2. 寄存器寻址方式 寄存器寻址方式是指寻找的操作数存放在某个寄存器中,在指令中指定寄存器号。这里的寄存器可以是8位的(AL,AH,BL,BH,CL,CH,DL,DH),也可以是16位的(AX,BX,CX,DX,SI,DI,SP,BP)。 这种寻址方式的特点是: 寄存器数量一般在几个到几十个,比存储器单元少很多,因此它的地址码短,从而缩短了指令长度,节省了程序存储空间。另一方面,从寄存器里取数比从存储器里取数的速度快得多,从而提高了指令执行速度。 【例54】MOVAX,BP 这条指令的执行结果是将寄存器BP中的内容送到寄存器AX中。如果执行前(AX)=0000H,(BP)=1122H,则指令执行后(AX)=1122H,BP中的值不变。这条指令的执行情况如图54所示。 图54寄存器寻址方式示意图 注意: 以上的两种寻址方式在寻找操作数的过程中没有涉及存储器,所以千万不要理解为和内存操作有关系。 3. 存储器寻址方式 当操作数存放在存储器中的某个单元时,CPU要访问存储器才能获得该操作数。要访问存储器中的某个单元,就必须知道该单元的地址。如果存储器的存储单元地址是20位(物理地址),而在指令中一般只会给出段内偏移地址(有效地址),需结合段地址形成20位物理地址,才能找到操作数。通过指令中各种不同的形式计算出有效地址的方法就构成了不同的存储器寻址方式。下面分别进行介绍。 (1) 直接寻址方式。 直接寻址方式是指寻找的操作数的有效地址在指令中直接给出,即指令中直接给出的16位偏移地址就是操作数的有效地址。该有效地址存放在代码段中的指令操作码之后,其中低8位为低地址,高8位为高地址。但如果没有特殊说明,操作数通常存放在数据段中,所以必须求出操作数的物理地址,然后再访问存储器才能够获得操作数。操作数的物理地址通过段寄存器和有效地址求得。例如,若数据存放在数据段中,那么它的物理地址为数据段寄存器DS左移4位再加上16位的偏移地址。 【例55】MOVAX,[1000H] 如果(DS)=30000H,(31000H)=56H,(31001H)=34H。操作的示意图如图55所示。指令执行完以后,(AX)=3456H。 图55直接寻址方式示意图 需要注意的是,这条指令的功能是将数据段中的偏移地址为1000H和1001H的存储单元中的内容送到AX中,而不是立即将数1000H送到AX中。 小知识: 直接寻址方式默认的段寄存器是DS,也就是操作数存放在数据段。 如果操作数不是存放在数据段中,则需要在偏移地址前加上段超越前缀。 思考: 直接寻址方式和立即数寻址方式的主要区别是什么? 【例56】MOVAL,ES: [2000H] 这条指令的执行结果是,将附加段中偏移地址为2000H的存储单元中的内容送入AL寄存器中。 (2) 寄存器间接寻址方式。 寄存器间接寻址方式是指操作数的有效地址在基址寄存器(BX、BP)或变址寄存器(SI、DI)中,而操作数则在存储器中。寄存器间接寻址方式与寄存器寻址方式的区别在于指令中指示的寄存器中的内容不是操作数,而是操作数的偏移地址。 寄存器间接寻址方式的特点是: 指令中给出的寄存器号必须使用方括号[ ]括起来,以便和寄存器寻址方式相区别; 由于寄存器中存放的是操作数的偏移地址,因此指令在执行过程中要访问存储器一次。 【例57】MOV AX,[BX] MOV AX,[SI] 其中“[BX]”“[SI]”都是寄存器间接寻址方式。 在使用寄存器间接寻址方式时,需要注意以下几点。 (1) 寄存器间接寻址方式可用的寄存器只能是基址寄存器(BX、BP)或变址寄存器(SI、DI)中的一个,通常将这四个寄存器简称为间址寄存器。 (2) 选择不同的间址寄存器,涉及的段寄存器也不同。如果指令中指定的寄存器是BX、SI、DI,则操作数默认在数据段中,取DS寄存器的值作为操作数的段地址值; 如果指令中指定的寄存器是BP,则操作数默认在堆栈段中,取SS寄存器的值作为操作数的段地址值,从而计算得到操作数的20位物理地址,继而访问到操作数。 (3) 不论选择哪个间址寄存器,指令中都可以指定段超越前缀来获得指定段中的数据。 【例58】MOV AX,[BX] 如果(DS)=30000H,(BX)=1010H,(31010H)=12H,(31011H)=24H。则操作数的20位物理地址=30000H+1010H=31010H,操作的示意图如图56所示。 指令执行完以后,(AX)=2412H。 图56寄存器间接寻址方式示意图 【例59】MOVAX,ES: [BX] 这条指令表示将附加数据段偏移量(BX)处的字节数据送到AX寄存器中去。 这种寻址方式一般用于访问表格,执行完一条指令后,通过修改SI、DI、BX或BP的内容就可访问表格的下一数据项的存储单元。 (3) 寄存器相对寻址方式。 寄存器相对寻址方式是指操作数的偏移地址是指令中指定间址寄存器的内容与指令中给出的一个8位或16位偏移量之和。操作数默认位于哪个段中,是由指令中使用的间址寄存器决定的。指令中指定的寄存器是BX、SI、DI、BP时,它们与操作数默认存放位置和段地址值的对应关系情况同寄存器间接寻址方式中一样。 寄存器相对寻址方式的特点是: 指令中给出的8位或16位偏移量是相对于间址寄存器而言的,因此可以把寄存器相对寻址方式看成是带偏移量的寄存器间接寻址。这种寻址方式一般用于访问表格,表格首地址可设置为变量名,通过修改SI、DI、BX或BP的内容来访问表格的任一数据项的存储单元。 【例510】DISP是数据段中16位偏移量的符号地址,假设它为0100H,有指令: MOVAX,DISP[SI] 若(DS)=20000H,(SI)=00A0H,(201A0H)=12H,(201A1H)=34H,则源操作数的20位物理地址=20000H+0100H+00A0H =20000H+01A0H =201A0H。 操作的示意图如图57所示,这条指令的执行结果为(AX)=3412H。 图57寄存器相对寻址方式示意图 在汇编语言中,相对寻址的书写格式非常灵活,例510中的指令还可以写成以下的任何一种形式: MOVAX,[DISP+SI] MOVAX,[SI+DISP] MOVAX,[SI]+DISP MOVAX,DISP+[SI] MOVAX,[SI]DISP 对于寄存器相对寻址,也可用段超越前缀重新指定段寄存器。 【例511】MOVAL,ES: DISP[SI] 这条指令虽然使用了SI作为间址寄存器,但是同时使用了段超越前缀ES,因此操作数是存放在附加段中,而不是默认的数据段中。故而必须使用ES而不是DS作为段地址来计算操作数的物理地址。这条指令的执行结果是将附加段中偏移地址为(SI)+ DISP的存储单元中的内容送入AL中。 思考: 寄存器间接寻址和寄存器相对寻址的区别是什么? (4) 基址变址寻址方式。 基址变址寻址方式是指操作数的偏移地址是一个基址寄存器(BX、BP)和一个变址寄存器(SI、DI)的内容之和。基址变址寻址方式的格式表示为: [基址寄存器名][变址寄存器名]或[基址寄存器名+变址寄存器名]。操作数默认位于哪个段中,是由指令中使用的基址寄存器决定的,同寄存器间接寻址方式中介绍的对应关系一样。 基址变址寻址方式的特点是: 指令中使用的两个寄存器都要用方括号[ ]括起来,表示寄存器中的内容不是操作数而是偏移地址。 【例512】MOV AX,[BX][SI] 或写为: MOV AX,[BX+SI]。 其中“[BX][SI]”“[BX+SI]“都是基址变址寻址方式。 【例513】MOVAX,[BX][SI]或写为MOVAX,[BX+SI]。 若(DS)=20000H,(BX)=0500H,(SI)=0010H, 则偏移地址=0500H+0010H=0510H。 20位物理地址=20000H+0510H =20510H。 如(20510H)=12H,(20511H)=34H, 操作的示意图如图58所示,这条指令的执行结果为(AX)=3412H。 图58基址变址寻址方式示意图 当然,也可用段超越前缀重新指定段寄存器,如: MOVAL,ES: [BX][SI] 这种寻址方式同样可用于访问表格或数组。将表格或数组首地址存入基址寄存器,通过修改变址寄存器内容可访问到表格或数组的任一数据项的存储单元。由于这种寻址方式两个寄存器内容都可修改,因此它比寄存器相对寻址更灵活。 (5) 相对基址变址寻址方式。 相对基址变址寻址方式是指操作数偏移地址是一个基址寄存器和一个变址寄存器以及一个8位或16位偏移量之和。操作数默认位于哪个段中,是由指令中使用的基址寄存器决定的,同寄存器间接寻址方式中介绍的对应关系一样。 【例514】MOVAL,TABLE[BX][SI] 其中“TABLE [BX][SI]”是相对基址变址寻址方式,也可写成 MOVAL,TABLE[BX+SI] 或MOVAL,[TABLE+BX+SI] 【例515】TABLE是数据段中定义的一个符号地址,假设它在数据段中的偏移地址是1000H。 MOVAX,TABLE[BX][DI] 若(DS)=20000H,(BX)=0100H,(DI)=0020H, 则偏移地址=1000H+0100H+0020H=1120H。 20位物理地址=20000H+1120H=21120H。 如(21120H)=12H,(21121H)=34H, 操作的示意图如图59所示,执行完指令以后(AX)=3412H。 图59相对基址变址寻址方式示意图 思考: 基址变址寻址和相对基址变址寻址的区别是什么? (6) 隐含寻址方式。 隐含寻址方式是指在指令中没有明显地给出部分操作数的地址,而是隐含于指令码中。例如,在乘法指令MUL中,只给出了乘数的地址,而被乘数的地址以及乘积结果的存放地址都是隐含的,被乘数的地址固定取AL,乘积结果的存放地址固定取AX。例如,指令MUL BL的执行结果为(AL)×(BL)→(AX)。因此,乘法指令中的AL和AX属于隐含地址。 5.4.2活动2详解指令寻址 指令寻址是指如何确定下一条将要执行的指令所在的地址,即形成指令转移地址的方法。 指令寻址主要有顺序寻址方式和跳转寻址方式两种。顺序寻址方式指通过程序计数器PC自动形成下一条指令的地址; 跳转寻址方式则通过转移指令来实现。 1. 顺序寻址方式 通常情况下,程序是按照书写的顺序一条接一条地执行,即先从存储器中取出第1条指令,然后执行第1条指令; 接着从存储器中取出第2条指令,然后执行第2条指令; 依次执行下去。这种方式就是指令的顺序寻址方式。为了实现顺序寻址,需要使用程序计数器PC来保存指令的地址,每执行完一条指令后,PC的值进行自加,形成下一条指令的地址。程序执行时总是从程序计数器中获取将要执行的指令地址。对于采用字节编址的存储系统,PC每次自加的值要根据指令的长度来确定,对于1字节长的指令,PC每次自加的值为1; 对于2字节长的指令,PC每次自加的值为2; 对于4字节长的指令,PC每次自加的值为4。 图510所示为顺序寻址方式示意图。假设程序在内存中存放的起始地址为1000H,程序从地址为1000H处的指令开始执行,此时程序计数器中的值为1000H,第1条指令执行完成后,程序计数器的值自动加2,于是顺序执行第2条指令。第2条指令执行完成后,程序计数器的值再自动加2,继续顺序执行第3条指令。 图510指令的顺序寻址方式示意图 2. 跳转寻址方式 当程序在执行过程中遇到转移指令时,指令的寻址就会采取跳转寻址方式。所谓跳转寻址,是指下一条指令的地址不是通过程序计数器自加获得的,而是通过本条指令给出。通过使用本条指令给出的转移地址更新程序计数器的内容,完成指令地址的转移。 图511所示为指令长度为3字节的跳转寻址方式示意图。假设程序顺序执行到第4条指令,也就是转移指令JMP 100D。第4条指令执行的结果就是把地址100D装载到程序计数器中,因此下一条要执行的指令地址为100D,也就是第7条指令。由于第7条指令不是转移指令,因此这条指令执行完成后,程序计数器自动加2。因此,下一条将执行的指令就是地址为100F的指令,即第8条指令。 图511指令的跳转寻址方式示意图 3. 8086 CPU中的跳转寻址方式 跳转寻址是指指令突破顺序执行的限制,而转向另一个地址来执行,这种地址的转移在Intel 8086 CPU中是通过修改CS和IP的值来实现的。跳转寻址方式可分为段内寻址和段间寻址两类。由于段内寻址方式的转向地址仍在本代码段内,因此只需修改IP的内容,不需要修改CS的内容; 而段间寻址方式由于其转向地址不在原代码段内,因此IP和CS的内容都要发生变化。 (1) 段内直接寻址方式。 段内直接寻址方式下转向的有效地址是当前IP寄存器的内容与指令中给出的8位或16位偏移量之和,此求和结果将成为新的IP寄存器值。这种寻址方式下转向的有效地址是通过相对于当前IP的偏移量来表示的,因此是一种相对寻址方式。这就保证了不论程序段在哪块内存区域中运行,都不会影响转移指令本身。段内直接寻址方式示意图如图512所示。 图512段内直接寻址方式示意图 使用段内直接寻址方式时,需要注意以下几点。 ① 偏移量可以是正值,也可以是负值。 ② 既适用于条件转移,也适用于无条件转移。 ③ 这种寻址方式是条件转移指令唯一可以使用的一种寻址方式,并且当用于条件转移时只能使用8位偏移量。对于JMP和CALL,可使用跳转寻址方式4种方式中的任何一种。 ④ 当用于无条件转移时,若偏移量为8位,称为段内直接短转移,转移范围是-128~+127,在指令中需在转向的符号地址前面加操作符SHORT; 若偏移量为16位,称为段内直接近转移,转移范围是-32768~+32767,在指令中需在转向的符号地址前面加操作符NEAR PTR。 ⑤ 指令中通常使用符号地址来指定偏移量,也就是需要程序在执行过程中计算符号地址与转移指令之间的距离。 【例516】JMPSHORTFUNC 这条指令将实现段内直接短转移,其中FUNC为程序中的符号地址。 (2) 段内间接寻址方式。 段内间接寻址方式下转向的有效地址是一个寄存器或一个存储单元的内容,这一内容将成为新的IP寄存器值。这个寄存器或存储单元的内容可以通过上面讲的除立即寻址方式以外的任何一种数据寻址方式获得。另外段内间接寻址方式不能用于条件转移指令,段内间接寻址方式示意图如图513所示。 图513段内间接寻址方式示意图 【例517】JMPAX 这条指令的寻址方式是段内间接寻址。 转向的有效地址存放在寄存器AX中。若(AX)=2000H,则指令执行后(IP)=2000H。 【例518】JMPFUNC[BX] 这条指令的寻址方式是段内间接寻址。 转向的有效地址存放在数据段中偏移量为BX+FUNC的存储单元中,其中FUNC为程序中的符号地址。 若(DS)=20000H,(BX)=2288H,FUNC=1020H,(232A8H)=5020H,则指令执行后(IP)=(20000H+2288H+1020H)=(232A8H)=5020H。 思考: 段内直接寻址和段内间接寻址的区别是什么? 图514段间直接寻址方式示意图 (3) 段间直接寻址方式。 段间直接寻址方式下使用指令中直接给出的16位段地址和16位偏移量来分别取代CS和IP的内容,从而实现段间的转移。段间直接寻址方式示意图如图514所示。 【例519】JMPFAR PTREXTFUNC 这条指令使用直接寻址方式完成段间的转移,其中EXTFUNC为转向的符号地址,存放着CS和IP的新值; FARPTR为段间转移的操作符。 (4) 段间间接寻址方式。 段间间接寻址方式下使用存储器中连续两个字的内容分别取代CS和IP寄存器中原来的内容,每个字在存储器中占用2字节,其中高地址单元的字取代CS值,低地址单元的字取代IP值。保存转向地址的存储单元的有效地址可以通过除立即寻址方式和寄存器寻址方式以外的任何一种寻址方式来获得,段间间接寻址方式示意图如图515所示。 图515段间间接寻址方式示意图 【例520】JMPDWORD PTR [BX+FUNC] 这条指令使用段间间接寻址方式实现指令的跳转。其中BX+FUNC为数据段中存放转向地址的偏移量,DWORD PTR为双字操作符,说明转向地址将取两个字。指令的执行结果是将数据段中偏移量为BX+FUNC和BX+FUNC+1地址单元的内容送到IP中,偏移量为BX+FUNC+2和BX+FUNC+3地址单元的内容送到CS中。 思考: 段间直接寻址和段间间接寻址的区别是什么? 5.5任务5学习8088/8086 CPU的指令系统 本任务中主要包含的内容有数据传送指令、算术运算指令、逻辑运算和移位指令、串操作指令、控制转移指令和处理器控制指令。如果想学习各类指令的具体内容可扫描此处二维码。 视频讲解 5.5节扩展内容 5.6项目总结 项目5介绍了指令系统和寻址方式。指令系统是构成计算机系统的主要部分。一台计算机所能执行的所有动作构成它的指令系统,指令系统也指示着计算机系统的能力。指令的种类非常多,常见的指令有数据传送指令、运算指令、移位指令等。不同的指令其完成的动作是不一样的,进而其消耗的时间也是不一样的,因此描述指令的执行周期要借助于中央处理器的时钟周期。指令周期由取指令周期、取操作数周期和执行指令周期构成。 计算机的工作过程就是在不停地寻址指令地址的过程。指令分为零地址指令、一地址指令、二地址指令和多地址指令,每一条指令都有地址。寻找地址指令就是寻址操作数的地址。由于操作数存放位置的不同,寻址分为立即寻址、寄存器寻址和存储器寻址。 最后介绍了16位操作系统8088/8086 CPU的指令系统,这部分内容与汇编语言契合,可以作为学习计算机硬件和计算机语言的基础部分。 5.7拓展训练 1. 一般来说,每条指令包含()和地址码。 A. 操作码B. 数据码C. 逻辑码D. 控制码 2. 在直接寻址方式中,指令中的地址码是()。 A. 操作数B. 操作数地址C. 指令地址D. 变址地址 3. 指令包括操作码和操作数(地址码),大多数指令需要双操作数,分别称为()和()。 A. 源操作数和目的操作数B. 源操作数和逻辑操作数 C. 逻辑操作数和目的操作数D. 逻辑操作数和状态操作数 4. 取出并执行一条指令的时间为()。 A. 指令周期B. 机器周期C. 取指周期D. 执指周期 5. 在下面的寻址方式中,()速度最快。 A. 立即寻址B. 间接寻址C. 直接寻址D. 变址寻址