




已阅读5页,还剩12页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第五章 LC-3在第四章中,我们讨论了计算机的基本组件:存储器,处理单元(包括相关的临时存储单元,通常是一组寄存器),输入和输出设备,以及控制所有单元(包括它本身)行为的控制单元。我们还介绍了指令周期的6个阶段:取指令,译码,计算地址,取操作数,执行和存储结果。下面,我们就准备研究一个“真实”的计算机LC-3,确切的说,是介绍LC-3的指令集结构(ISA)。在第四章里,已经对其行为和其中的几条指令作了介绍,本章将深入研究LC-3的指令集结构。在第一章中我们曾经提到,指令集结构是软件命/指令和执行命令的硬件之间的接口,在本章以及第八章和第九章,我们将指出LC-3的指令集结构的重要特性。利用这些特性,就可以使用LC-3自己的语言编写程序,即LC-3机器语言。附录A包含了有关LC-3指令集结构的详细信息。5.1 指令集结构:概要指令集结构(ISA)指明了在一台机器上编写软件时所要注意的全部信息。换句话说,ISA规定了程序员使用机器语言编程时的全部信息。对于那些将使用高级语言,如C、Pascal或Fortran、COBOL写的程序翻译成计算机机器语言的人,ISA也提供了关于该计算机的所有可用信息。ISA规定了存储器的组织,寄存器集和指令集,包括操作码,数据类型和寻址模式。5.1.1 存储器组织 LC-3的存储器有216(即65536)个地址空间的单元,16位的寻址能力。不是所有的65536个地址都用作存储单元,对此我们将在第八章作详细说明。既然LC-3通常处理的数据单元都是16比特大小,我们把16比特称作一个字,我们说LC-3是字可寻址的。5.1.2 寄存器 鉴于从存储器中读取数据花费的时间通常远长于一个机器周期,LC-3(像大多数计算机一样)提供了可以在一个机器周期内访问数据的附加的临时存储空间。 最常用的一种附加临时存储空间就是LC-3所采用的是通用寄存器集。这个集合中的寄存器都被称作通用寄存器(GPR)。寄存器拥有和存储单元相同的性质可以用来存储信息,这些信息不久后就会被读取。存储在每一个寄存器中的位数通常是一个字。在LC-3中,意味着是16位。寄存器必须是能够被唯一识别的。LC-3定义了8个通用寄存器,使用3位编码来识别,分别被标记为R0、R1R7。图5.1显示了LC-3的寄存器集的一张瞬态图,有时被称为寄存器堆,在R0,R1R7中分别存储1,3,4,7,-2,-4,-6和-8这8个值。回忆(第四章)把R0和R1中的数值相加得到的结果存入R2中的加法指令为:15141312111098765432100001010000000001ADDR2R0R1这个加法指令的两个加数用8:6位和2:0位表示,相加的结果存入的目标由11:9位表示。图5.2显示了在ADD R2,R1,R0指令执行之后的图5.1的寄存器堆的内容。5.1.3 指令集一条指令由两部分组成,即它的操作码(指令让计算机做的事情)和操作数(计算机操作的对象)。ISA的指令集是由一组操作码、数据类型和寻址模式定义的。寻址模式决定了操作数位于什么地方。前面的例子就是一个操作码为ADD,寻址模式是寄存器模式的指令。该指令的操作是让计算机做二进制补码整数的加法,计算机寻找的操作数的位置是位于通用寄存器中的。5.1.4 操作码 有些ISA有一个非常大的操作码集,每一个操作码对应了一个程序中可能要执行的众多任务中的一个。有些ISA则拥有一个非常小的操作码集。有些ISA有专门的操作码来处理科学计算,例如,HP的Precision Architecture中有一条指令是执行一个先乘后加的如(A*B)+C的三目运算。而有些ISA有用来处理从万维网获得的视频图像信息的指令,如Intel x86 ISA 加入了许多被称为MMX的指令,因为它们扩展(eXtend)了ISA指令集以帮助处理网络上的多媒体(MultiMedia)应用。还有其他的一些ISA加入了专门的操作码来帮助支持操作系统的任务,例如在二十世纪八十年代盛行的VAX体系, 有一个专门的指令,用来在一个正在运行的程序切换到另一个程序之前,保存那个正在运行的程序的所有信息,而几乎所有的计算机都用一长串的指令使计算机实现保存那些信息的任务。当一个新的ISA被定义时,关于某条指令的去留问题,总是要有一番激烈的争论。LC-3 ISA有15条指令,每一条指令由不同的操作码来区分。操作码是由指令的15:12位定义的。既然有4位用于操作码,其指令就有16种可能。然而,LC-3 ISA只定义了15条指令,1101码未被定义,被保留下来,用于我们今天还不能预测到的将来的需要。有三种不同类型的指令,即三种不同类型的操作码,分别是:运算,数据传送,控制。运算指令处理信息,数据传送指令在存储器和寄存器之间或在寄存器/存储器和输入/输出设备之间传送数据。控制指令改变指令被执行的顺序。换言之,它们使某一条指令而不是位于存储器中下一个位置的指令被执行。图5.3列出了LC-3的15条指令,15:12位代表各操作码。每指令的使用将在随后的第5.2、5.3和5.4节来阐述。5.1.5 数据类型数据类型是信息的表示方法。在计算机里有许多方法来表示相同的信息。在日常生活中,我们也使用许多不同的方法来表示相同的信息。例如,当我们问一个小孩,他有几岁时,他也许会伸出三个手指,代表三岁;他也许可以写下数字“3”;如果他是一个学计算机科学或计算机工程专业的大学生,他也许写下16位的二进制数0000000000000011来代替;如果他是化学专业的学生,可能使用3.0100来表示。这四种都是3的表示方法。如果ISA中有一个操作码能对某种数据类型表示的信息进行运算,我们就说该ISA支持这种数据类型。在第二章,我们介绍了LC-3的ISA支持的唯一一种数据类型:二进制补码整数。5.1.6 寻址模式寻址模式是一种指示操作数位置的机制。一般地,可能在三个地方找到操作数:存储器,寄存器,或指令中的一部分。如果操作数位于指令中的一部分,我们称之为字面或立即数。“字面”源于指令的若干位字面上构成操作数的事实,“立即数” 源于我们可以立即从指令中获得操作数的事实,也就是说,不用去别处寻找。LC-3支持五种寻址模式:立即数(或字面),寄存器和三种存储器寻址模式PC相对,间接,基址+偏移量。我们将在5.2节中介绍使用了两种寻址模式的运算指令:寄存器和立即数。在5.3节中介绍使用了五种模式的数据传送指令。5.1.7 条件码大多数ISA允许基于前一条指令产生的结果改变指令执行的顺序。LC-3有三个一位的寄存器,每当八个寄存器之一被改写时,它们可被设置为0或1。这三个一位的寄存器被称为N,Z,P。相应的意义:负数,零,正数。每当一个GPR(通用寄存器)被改写时,N,Z,P寄存器就会根据写到GPR的结果是否为负数,零,正数,分别设为0或1。也就是说,如果结果为负数,N为1,Z 和P清0;如果结果为0,Z设为1,N、P为0;结果为正数,P为1,N、Z为0。这三个寄存器被称为条件码的原因是可用此位作条件,来控制指令的执行顺序。x86和SPARC是两种使用条件码的ISA的例子。我们将在5.4节中介绍LC-3如何使用条件码。5.2 运算指令 运算指令对数据进行处理。常见的例子包括算术运算(像加、减、乘、除)和逻辑运算(像与、或、非、异或)。LC-3有三个运算指令:加、与、非。NOT指令(操作码是1001)是唯一一个进行一元运算的指令,也就是说,这个指令要求有一个源操作数。这个指令对一个16位的源操作数按位取反后把结果存入一个目标中。NOT对源操作数和目标操作数都采用寄存器寻址模式。8:6位对应的是源寄存器,11:9位对应的是目标寄存器,5:0位必须全部包含1。如果R5一开始存储的是0101000011110000,执行下面的指令后:15141312111098765432101001011101111111NOTR3R5R3中将会包含 1010111100001111。图5.4显示了用来执行NOT指令的数据通路的关键部分。既然NOT是一个一元运算,对于ALU,只有A输入是相关的。源操作数来自于R5,指挥ALU的控制信号是执行按位取反运算,ALU的输出(运算结果)被存储于R3中。ADD(操作码是0001)和AND(操作码是0101)指令都执行一个二元运算;它们需要两个16位的源操作数。ADD指令对两个源操作数执行一个二进制补码的加法运算。AND指令对它的两个16位源操作数执行一次按位与运算。像NOT一样,ADD和AND对其中一个源操作数和目标操作数采用寄存器寻址模式。8:6对应源寄存器,11:9对应目标寄存器(结果将被写入的地方)。ADD和AND的第二个源操作数可以通过寄存器寻址模式或立即数模式得到,由5位决定使用哪种方式。如果5位是0,那么第二个操作数要使用一个寄存器,2:0位对应着这个寄存器。这时,4:3位被全部设为0。例如,如果R4中存储数值6,R5中存储数值-18,执行下面的指令后:15141312111098765432100001001100000101ADDR1R4R5R1将会被写入数值-12。如果5位是1,第二个源操作数就被包含在指令当中。事实上,第二个源操作数是在执行ADD或AND操作之前,将4:0位执行符号扩展到16位得到的。图5.5显示了用来执行ADD R1,R4,#-2指令的数据通路的关键部分。既然ADD或AND指令的立即操作数必须位于指令的4:0位中,就不是所有的二进制补码整数都可以是立即数,那么,哪些整数可以用作立即数?例5.1 下面的指令是做什么的?15141312111098765432100101010010100000答案: 寄存器R2被清空。(也就是,被全部设为0)例5.2下面这条指令执行什么操作?15141312111098765432100001110110100001答案: 寄存器R6加1(就是说,R6R6+1)注意:在同一条指令中一个寄存器既可以作为源操作数也可以作为目标操作数。这对LC-3的所有指令都是适用的。例5.3 回想一下,取一个补码表示的数值的负数可以通过取反加1得到。因此,假设两个值A,B分别存在R0和R1中,如何执行A减B,再把结果存到R2中?答案:15141312111098765432101001001001111111 NOTR1R1R1 NOT(B)15141312111098765432100001010001100001ADDR2R11R2 -B15141312111098765432100001010000000010ADDR2R0R2R2A+(-B)问题:这组指令还会产生什么不好的结果?怎样做就能避免出现这个结果?5.3 数据传送指令数据传送指令可以在存储器和通用寄存器之间,存储器和输入/输出设备之间传送数据。现在我们将不研究怎样将数据从输入设备传送到寄存器和怎样将数据从寄存器传送到输出设备。这将是第八章的主题,同时它也是第九章的一个重要部分。在这一章,我们将集中精力去研究存储器和通用寄存器之间数据的传输。将数据从存储器移动到寄存器的过程叫加载(load)。而将数据从寄存器移动到存储器的过程叫存储(store)。在这两个过程中,源操作数所在位置的内容并没有改变。但目标操作数所在位置的内容被改写,原来的值便被破坏了。LC-3有7种数据传送指令:LD,LDR,LDI,LEA,ST,STR和STI。加载和存储指令的格式如下:1514131211109876543210操作码DR或SR地址生成位数据传送指令需要两个操作数:一个源操作数和一个目标操作数。源操作数是要传送的数据所在的位置,目标操作数是要传送到的位置。在两个操作数中,一个是寄存器,另一个是存储器单元或输入/输出设备。正如我们之前说过的,在本章,假设第二个操作数均位于存储器中。第二个操作数是输入/输出设备的情况我们留到第八章介绍。11:9位说明了第一个操作数,寄存器。如果指令是加载,DR指的就是目标寄存器,它将在从存储器读取数据之后,包含该数值(指令周期完成时)。如果指令是存储,SR指的就是包含要被写到存储器的数值的那个寄存器。8:0位包含了地址生成位,也就是说,8:0位编码的信息被用来计算第二个操作数的16位地址。在LC-3的情况中,数据传送指令有4种方式解释8:0位,它们合起来被称为寻址模式,由操作码说明如何解释8:0位。也就是说,LC-3的操作码说明如何从指令的8:0位获取操作数。5.3.1 PC相对寻址模式LD(操作码是0010)和ST(操作码是0011)指令规定了PC相对寻址模式;之所以命名为PC相对寻址模式,是因为指令的8:0位说明了一个相对于PC的偏移量。存储器地址通过将8:0位符号扩展为16位,然后与被增加过1的PC做加法计算得到。被增加过1的PC是在取指令阶段之后,即PC增加1之后,程序计数器中的内容。如果是加载指令,计算出的存储器地址对应的存储器单元被读取,结果被加载到被指令的11:9位说明的寄存器中。如果指令15141312111098765432100010010110101111LDR2x1AF被加载到x4018,会造成x3FC8的内容被加载到R2中。图5.6显示了执行这条指令所需的数据通路的相关部分。LD指令的3个步骤被标识出来。在第1步,被增加过1的PC(x4019)与IR8:0位经符号扩展后的值(xFFAF)相加,结果(x3FC8)被加载到MAR。在第2步,存储器被读取,x3FC8中的内容被加载到MDR,假设存在x3FC8中的值是5。在第3步,数值5被加载到R2,完成指令周期。注意,存储器操作数的地址被限于所有存储器中的一个很小的范围。也就是说,因为在加上偏移量之前,PC已经被增加1,所以那个地址只能在LD或ST指令的+256或-255的单元中,这是指令的8:0位经过符号扩展后,提供的范围。5.3.2 间接模式LDI(操作码是1010)和STI(操作码是1011)指令规定了间接寻址模式。第一次形成地址的方式与LD和ST相同。然而,这个地址不是要被加载或存储的操作数的地址,而是包含要被加载或存储的操作数的地址。因此,命名为间接寻址。注意,这个操作数的地址可以位于计算机存储器的任何地方,而不是像LD和ST那样,在指令的8:0位提供的范围内。LDI的目标寄存器和STI的源寄存器,就像其它所有的加载和存储指令一样,被指令的11:9位说明。如果指令15141312111098765432101010011111001100LDIR3x1CC位于x4A1B,且x49E8的内容是x2110,执行这条指令的结果是,x2110中的内容被加载到R3中。图5.7显示了执行这条指令所需的数据通路的相关部分。正如LD和ST指令那样,在第1步,被增加过1的PC(x4A1C)与IR8:0位经符号扩展后的值(xFFCC)相加,结果(x49E8)被加载到MAR。在第2步,存储器被读取,x49E8中的内容(x2110)被加载到MDR。在第3步,既然x2110不是操作数,而是操作数所在地址,它被加载到MAR。在第4步,存储器被再次读取,MDR再次被加载,此次MDR被加载的是x2110中的内容。假设存储在x2110中的值是-1。在第5步,MDR中的值(即-1)被加载到R3,完成指令周期。5.3.3 基址+偏移量模式LDR(操作码是0110)和STR(操作码是0111)指令规定了基址+偏移量寻址模式。之所以命名为基址+偏移量寻址模式,是因为操作数的地址是通过将6位的偏移量进行符号扩展后,与一个基址寄存器相加得到的。这6位的偏移量是从指令中得到的,是5:0位,基址寄存器被指令的8:6位说明。基址+偏移量寻址模式将6位的偏移量值用作二进制补码整数,在-32到+31之间。这样,在它与基址寄存器做加法之前,必须首先被符号扩展到16位。如果R2包含的16位数值是x2345,指令15141312111098765432100110001010011101LDRR1R2x1D将x2362中的内容加载到R1。图5.8显示了执行这条指令所需的数据通路的相关部分。首先,R2中的内容(x2345)与IR5:0经过符号扩展得到的值(x001D)相加,结果(x2362)被加载到MAR;第2步,存储器被读取,x2362中的内容被加载到MDR。假设存在x2362中的值是x0F0F。在第3步,MDR中的值(即x0F0F)被加载到R1。注意,基址+偏移量寻址模式也允许操作数的地址位于计算机存储器的任何地方。5.3.4 立即数模式被数据传送指令使用的第四种也是最后一种寻址模式是立即数(或字面)寻址模式。它只被用于加载有效地址(LEA)指令中。LEA(操作码是1110)将指令的11:9位说明的寄存器加载,被加载的数值是通过将增加过1的PC的值与指令的8:0位经符号扩展后相加得到的。之所以命名为立即数寻址模式,是因为被加载到目标寄存器的操作数是立即获得的,也就是说,不需要任何访问存储器的操作。LEA指令被用作初始化阶段,用一个非常靠近该指令所在地址的地址初始化某个寄存器。如果存储器单元x4018包含指令LEA R5,#-3,PC包含x4018,在x4018指令被执行后,R5将包含x4016。图5.9显示了执行LEA指令所需的数据通路的相关部分。注意,在获取被加载的值时,不需要访问存储器。此外,LEA也是唯一的在获取被加载到DR中的信息时,不需要访问存储器的指令。它将增加过1的PC与指令的地址生成位形成的地址加载到DR中。5.3.5 示例我们用一个复杂的例子结束寻址模式。假设存储器单元x30F6到x30FC的内容如图5.10所示,PC包含x30F6。我们检查一下执行这7条连续的指令后的效果。PC首先指向单元x30F6,就是说,PC中的内容是地址x30F6。因此,存储在单元x30F6中的第一条指令被执行。该指令的操作码是1110,标识为加载有效地址指令(LEA)。LEA将指令的8:0位符号扩展后,与增加过1的PC相加,形成的地址加载到被11:9位说明的寄存器中。通过指令的8:0位符号扩展后获得的16位的值是xFFFD,增加过1的PC是x30F7,因此,在LEA指令执行结束,R1包含x30F4,PC包含x30F7。第2条被执行的指令是存储在x30F7中的指令。操作码是0001,标识为ADD指令,将8:6位表示的寄存器中的内容与4:0位符号扩展后获得的立即数(既然5位是1)相加,结果存储在11:9位说明的寄存器中。因为前一条指令将x30F4的值加载到R1中,符号扩展后获得的立即数是x000E,则被加载到R2中的值是x3102。在该指令执行结束,R2包含x3102,PC包含x30F8,R1仍然包含x30F4。第3条被执行的指令存储在x30F8中。操作码是0011标识为ST指令,将指令的11:9位说明的寄存器中的内容,存储到使用PC相对寻址模式计算出地址的存储器单元中。也就是说,地址通过将增加过1的PC与指令8:0位符号扩展得到的16位值相加得到。指令8:0位通过符号扩展得到的16位值是xFFFB,增加过1的PC是x30F9,因此,在ST指令执行结束,存储器单元x30F4包含x3102,PC包含x30F9。在x30F9,我们找到操作码0101,表示AND指令,执行后,R2包含数值0,PC包含x30FA。在x30FA,我们找到操作码0001,表示ADD指令,执行后,R2包含数值5,PC包含x30FB。在x30FB,我们找到操作码0111,表示STR指令。STR指令使用基址+偏移量寻址模式(与LDR相同)。存储器地址通过将8:6位表示的寄存器(基址)中的内容,与5:0位符号扩展得到的偏移量相加获得。在这里,8:6位表示R1,R1的内容仍然是x30F4,符号扩展得到的16位偏移量是x000E,因为x30F4+x000E是x3102,因此存储器地址是x3102。STR指令将11:9位说明的寄存器中的内容存进x3102,11:9位表示的寄存器是R2。回忆前一条(位于x30FA)指令将数值5存进R2,因此,在该指令执行结束,存储器x3102包含数值5,PC包含x30FC。在x30FC,我们找到操作码1010,表示LDI指令。LDI指令使用间接寻址模式(与STI相同)。要获得存储器地址,首先采用PC相对寻址模式得到一个地址,在此,指令8:0位通过符号扩展得到的16位值是xFFF7,增加过1的PC是x30FD,它们的和是x30F4,这就是操作数地址所在的地址。存储器单元x30F4中包含x3102,因此,x3102是操作数地址。LDI指令将这个地址中的值(这里是数值5)加载到11:9位说明的寄存器中(这里是R3)。在该指令执行结束,R3包含数值5,PC包含x30FD。5.4 控制指令控制指令改变被执行的指令的顺序。如果没有控制指令,在当前指令结束后的下一个取指令阶段,将是位于下一个连续的存储器单元中的指令。这是因为PC在每条指令的取指令阶段增加了1。我们马上会看到,打破这个顺序通常很有用。LC-3有五个指令能使顺序流被打破。它们是:条件分支,无条件跳转,子程序(有时称为函数)调用,TRAP和从中断返回。在这一节中,我们只讨论最常见的控制指令:条件分支。我们也将介绍无条件跳转和TRAP指令。与其他相比,TRAP指令特别有用,因为它允许程序员从计算机输出、输入信息,而无需完全理解输入输出设备的复杂性。但是,大多数的有关TRAP的讨论和全部的关于子程序调用,从中断返回的内容,我们都将留到第九章和第十章进行。5.4.1 条件分支条件转移指令(操作码是0000)的格式如下:15141312111098765432100000NZPPCoffset11,10,9位分别对应5.1.7节介绍过的三个条件码。回忆,LC-3中所有的改写通用寄存器中数据的指令都要根据所写的数据值为正数,零还是负数,相应的设置三个条件码(即,1位的寄存器N,Z,P)。这些指令有ADD,AND,NOT,LD,LDI,LDR和LEA。条件码被条件分支指令使用,决定是否改变指令流。意思是,是否改变正常执行指令的顺序,这个顺序是在取指令的阶段PC加1的结果。指令周期如下:取指令和译码对所有的指令来说是一样的。在取指令的阶段PC加1。计算地址的阶段与LD和ST一样:通过将增加了1的PC,与8:0位通过符号扩展得到的16位值相加得到。 在执行阶段,处理器检查在指令中相应位为1的条件码(寄存器)。意思是,如果11位是1,条件码N被检验。如果10位是1,条件码Z被检验。如果9位是1,条件码P被检验。如果11:9位的任意一位是0,相应的条件码就不会被检验。如果任何一个被检测的条件码的状态是1,那么PC就被计算地址阶段得到的地址加载。如果被检测的条件码中没有一个状态为1,那么PC保持不变。在这种情况下,在下一个指令周期中,下一条连续的指令就会被取出来。例如,如果前一条指令是把0赋给某个通用寄存器,那么当前指令(存储在x4027)如下:15141312111098765432100000010011011001BRnzpx0D9将会加载PC的值为x4101,并且下一条将要被执行的指令在x4101而不是x4028。图5.11显示了执行这条指令所需的数据通路元件。注意,判定是否顺序的指令流会被打破所需的逻辑电路。在图中的情况下,输出是1,PC被x4101加载,而不是在条件分支指令的取指令阶段被加载的x4028。如果11:9位全部是1,那么所有的3个条件码都被检测。在这种情况下,因为刚刚运行的存储在寄存器里的结果不是正数就是负数或者0(没有其他的选择),3个条件码中肯定会有一种状态是1。既然三个条件码都被检测,PC就会被计算地址阶段得到的地址加载。因为指令流无条件的被改变,所以我们把这个叫做无条件分支,也就是说,与处理的数据无关。例如,下面的指令15141312111098765432100000111110000101BRnzpx185存储在地址x507B中,被执行,那么PC就会被加载为x5001。如果11:9位全部是0,会发生什么事情呢?5.4.2 一个例子我们准备通过一个简单的例子,向你展示指令集中控制指令的使用。假设我们知道x3100到x310B这12个地址中存储的是整数,我们希望计算这么多整数的和。图5.12是我们解决这个问题的算法的流程图。首先,和所有的算法一样,我们必须初始化变量。也就是说,必须赋予计算机解决这个问题所执行的程序所需要的变量初始值。有三个这样的变量:下一个被加的整数的地址(使用寄存器R1),当前的和(使用寄存器R3),和没有被做加法的整数的个数(使用寄存器R2)。这三个变量的初始化如下:第一个整数的地址存入R1,R3记录运行得到的和,初始化为0,R2记录剩下的未被加过的整数数目,初始化为12。然后加法开始进行。这个程序重复以下过程:加载12个数中的一个到R4,加到R3中。我们每执行一次加法,就递增R1,这样R1会指向下一个要被加的数字(即地址),并且递减R2,以此知道还有多少数字等待着被加。当R2中存储的数据变为0的时候,条件码Z被设置为1,因此我们可以检测到计算结束。图5.13中的这个10条指令的程序完成了这项任务。这个程序执行的细节如下:程序开始于PC=x3000的位置。第一条指令(存放的地址为x3000)将R1加载为地址x3100(被增加了1的PC是x3001,符号扩展的PC偏移量是x00FF)。x3001中的指令是清空R3。R3保存的是运行累加的结果。所以R3一定要从0开始。就像我们上面所说的,这个叫做初始化SUM为0。x3002和x3003的指令是把12赋给R2,12是表示有多少个数据将要被相加,R2中记录的是已经有多少个数字被加。这个数字将会在做完每一步加法后被减1(由x3008中的指令实现)。在x3004中的指令是条件分支语句,注意10位是一个1,那意味着Z条件码将会被检查,如果为1,我们就知道一定是R2刚刚被减少到0。这意味着没有更多的数字需要我们去加了,加法结束。如果为0,我们就知道我们仍然有工作要做,所以继续。在x3005的指令向R4里面加载了x3100里面的内容(第一个整数),而x3006这条指令把R4中的内容加到R3中。在x3007和x3008的指令执行的必须的记录工作,在x3007中的指令将R1增加1,所以R1将指向了存储单元中的包含下一个被加的整数的地址(在这里是x3101)。在x3008处的指令让将R2递减1,记录仍需被加的整数的数量,如同我们已经解释的,它同时设置了N,Z和P条件码。在x3009处的指令是一个无条件分支语句, 因为二进制指令代码中的11:9位全为1。它将地址x3004给PC,同时它也不影响条件码,因此,下一条被运行的指令 (在x3004的条件分支语句) 将会基于x3008中被执行的指令。值得再提一次的是,在x3004处的条件分支指令紧跟在x3009之后,x3009是一个并不影响条件码的指令,而其又依次跟随在x3008处的指令之后。所以,在x3004处的条件分支指令将会以在x3008中的指令被设定的条件码为基础。而在x3008处的指令根据寄存器R2递减1后的值设定条件码。只要仍然有整数需要被加,那在x3008处的ADD指令将会生成一个大于零的值,因此将条件码Z设为0。在x3004处的条件分支指令检查Z条件码。只要Z为0,PC将不受影响,下一个指令周期将会从在x3005处取指令开始。条件分支指令使得指令按以下顺序运行:x3000,x3001,x3002,x3003,x3004,x3005, x3006,x3007,x3008,x3009,x3004,x3005,x3006,x3007,x3008,x3009,x3004,x3005,等等直到寄存器 R2中的值变成0。那时, 在x3004处的条件分支指令被执行,PC被x300A加载,程序在x300A继续它的下面的行为。最后,值得注意的是,不使用控制指令,我们也能写加12个整数的程序。我们在x3000仍然需要LEA指令初始化R1。在x3001,我们不需要初始化一个累加和的指令,在x3002和x3003,也不需要初始化剩下被加的整数数目。我们将x3100的内容直接加载给R3,然后重复加剩下的11个整数(通过增加R1,加载下一个值给R4,将R4加到累加和R3上)。在第12个整数的加法之后,我们做下一项工作。这与图5.13在x3004使用分支指令的例子做的一样。不幸的是,它不是10条指令的程序,可能需要35条指令。不仅如此,如果我们希望增加100个整数而不是12个,不使用控制指令,我们将需要299条指令的程序,而不是10条。图5.13中的控制指令的例子通过打破顺序的指令执行流,允许了一组指令的重用。5.4.3 控制循环的两种方法循环这一术语描述了一个可以在某种控制机制下一次又一次运行的指令序列。将12个整数相加的例子中就包含一个循环。循环体每运行一次,又一个整数被加到运行的总和上,并且计数器递减1,以便我们检查是否还有遗留的整数未被加上。每一次循环体的运行被称做循环的一次重复。为控制一个循环的重复次数有两个通常的方法。有一种方法我们刚刚讨论过:使用计数器。如果我们知道想要执行循环n次,我们只要将计数器设置为n,然后在执行完每次循环后,就让计数器递减并且检查它是否为零。如果它不为零,就设置PC为循环的开始并且开始另一次重复。第二种控制循环执行次数的方法是使用标记。如果事先我们不知道想要执行多少次重复,这种方法是非常有效的。每一次重复通常都是建立在处理某个数值的基础上的。我们在要处理的那组数据后面加上一个预先知道不可能出现的值(即标记)。举个例子,如果我们在一组数据后添加一个标记,可以是一个“#”或者“*”,也就是一个不是数字的数据。我们的循环测试就只需测试标记的出现。当我们找到它的时候,就知道已经完成了循环。5.4.4 示例:利用标记加一列数假设在5.4.2节的例子中,我们知道存储在x3100到x310B都是正数。那么我们就可以使用任意一个负数作为标记,假设存储在存储器地址x310C中的标记为-1。这个程序的流程图如图5.14所示,程序如图5.15所示。与5.4.2节相同,在x3000中的指令把第一个将要被加的数值的地址加载到R1中,然后在x3001初始化R3(用来记录总和)到0。在x3002,我们把下一个存储器地址的内容加载到R4中。一旦作为标记的数字被加载到R4中,那么条件码N就被设为1。在x3003的条件转移指令检验条件码N,如果为1,PC就会被设为x3008,执行下一个要执行的任务。如果为0,R4中肯定还有有效的数字需要做加法。在这种情况下,这个数字被加到R3中(x3004),R1加,以指向下一个存储器地址(x3005),而下一个存储器地址中的数字又会被加载到R4中(x3006),PC则被加载为x3003,开始下一次重复(x3007)。5.4.5 JMP指令尽管条件分支指令有一定能力,但是存在一个不幸的限制。下一条被执行的指令必须位于某个地址范围内,其地址通过将增加了1的PC与指令的8:0位进行符号扩展得到的偏移量相加得到。既然8:0位表示一个二进制补码整数,在条件分支后执行的下一条指令只可能位于该分支指令的+256到-255的位置。要是我们想执行的下一条指令位于距当前指令1000的位置上,如何实现?我们无法使用9位表示出1000,因此,条件分支指令不能使用。LC-3的ISA提供了一条可以实现这项任务的JMP指令(操作码是1100)。例如:15141312111098765432101100000010000000JMPR2JMP指令将指令8:6位表示的寄存器中的内容加载到PC中。如果JMP指令位于x4000,R2包含x6600,PC包含x4000,那么位于x4000的指令(JMP指令)被执行后,位于x6600的指令就会被执行。既然寄存器包含16位,即可以表示存储器的全部地址空间,所以JMP指令对于下一条被执行的指令位于何处没有限制。5.4.6 TRAP指令最后,虽然距第九章还有一定距离,但是由于数据的输入和输出非常有用,现在就介绍TRAP指令。TRAP指令(操作码是1111)改变了PC,使其指向属于操作系统的某一部分的存储器地址,作用是为了让操作系统代表正在执行的程序执行一些任务。用操作系统的术语来说,TRAP调用了一个操作系统的“服务调用”。TRAP指令的7:0位为“TRAP向量”,标明程序希望操作系统执行哪一个服务调用。表.2包含了本书中我们用到的LC-3里的所有服务调用的TRAP向量。一旦操作系统执行完服务调用,PC将会指向TRAP下面一条指令的地址从而使程序继续。使用这种方式,一个程序可以在它执行时,要求操作系统提供服务并且在每个这样的服务完成后继续执行。我们现在需要的服务是:l 从键盘输入一个字符(TRAP向量x23)l 向显示器输出一个字符(TRAP向量x21)l 停止程序(TRAP向量x25)LC-3是如何执行操作系统和执行的程序之间的交互的?这是一个很重要的主题,将在第九章具体讨论。5.5 另外一个例子:计算字符出现次数我们将通过另外一个例子来结束LC-3的ISA这个部分的介绍。我们会通过从键盘输入一个字符,然后计算出这个字符在文档中出现的次数,最后,让显示器显示出这个计数。我们通过假设每个我们感兴趣的字符出现频率都很小的这样一种方法简化这个问题。也就是说,每个字符出现的次数都必须不大于九次,这种简化让我们不必担心二进制的计数器与在屏幕上显示的ASCII码之间的复杂的转换程序这一主题将在第十章详细讨论。图5.16为解决这个问题的算法流程图,注意每一步都以英语和以LC-3实现的术语(在括号里)来表示。第一步是(一如既往)是初始化所有的变量,这就是给R0,R1,R2和R3赋初值,计算机将使用这四个寄存器执行要解决的问题的程序。R2用来记录字符出现的次数,在图5.16中,它被看作是计数器,被初始化为0。R3指向被检查的文档中的下一个字符,我们称它为指针,因为它包含了我们希望检查的文档的下一个字符的存储地址。这个指针将被初始为文档中第一个字符的存储地址。而R0则被用来保存被计数的字符,我们从键盘键入一个字符,并将它存入R0中。R1用来保存每个将被检查的从文档中取出的字符。还有一点值得注意的是,我们要检查的文档不需要靠近或远离程序。例如,程序起始于x3000,而我们检查的文档起始于x9000是非常合理的。如果是那种情况的话,在初始化过程中,R3将被初始化为x9000。接下来一步就是计算输入的字符的出现次数,这一步就是处理被检查的文档中的每个字符,直至检查完为止。处理每个字符都需要一次重复,回忆5.4.3节的内容,有两种常规方法用于处理循环问题,在此,我们将采取标记法,使用EOT(文本结束)的ASCII码(00000100)作为标记。ASCII码表位于附录E中。在每次循环过程当中,R1中所存储的内容将首先与EOT的ASCII码做比较,如果相同,循环就结束,程序直接跳转到最后一步,直接在屏幕上输出字符出现的次数。如果不同,就表明还有工作要执行,R1(当前正在被检查的字符)将会与R0(从键盘输入的字符)相比较,如果匹配,R2加1,否则,就取下一个字符,也就是说,R3加1,下一个字符被再次存入R1,并且程序返回到检查文档是否结束的位置。当到达文档结尾时,所有字符都已被检查过,并且计数器以二进制形式被保存于R2中。为了使它在屏幕上显示,必须先把它转换为ASCII码。由于我们假设计数器小于10,也就是说,只要在计数器的四位二进制表示前加上一个0011即可。注意附录E.2中每个十进制数0到9的二进制值与其对应的ASCII码之间的关系。最后,计数器被输出到屏幕上,程序结束。图5.17是实现图5.16中的流程图的机器语言程序。首先是初始化的步骤。在x3000的指令利用把R2和x0000做与运算(AND)的方法把R2清零;在x3001的指令把保存在x3012的值加载到R3里。这是我们要检查字符出现次数的文档的第一个字符所在的地址,再次注意,该文档可以位于存储器的任意位置。在开始执行x3000之前,必须有一组指令将文档的起始地址存储到x3012。x3002中存储一条请求操作系统代表该程序执行一个服务调用的TRAP指令。这个以8位的陷入向量00100011(也就是,x23)表示的被请求的功能是从键盘得到一个字符的输入,并将其加载入R0。表A.2列出了所有能代表用户程序执行的操作系统服务调用的陷入向量。注意(在表A.2中),x23引导操作系统执行的服务调用为读入下一个输入的字符并将其加载到R0。在x3003的指令把由R3所指的字符加载到R1里。然后开始检查字符。从x3004开始,把R1的值减去4(EOT的ASCII码),并保存到R4。如果结果为零,则表明已到达文件结尾,是时候输出计数器的值了。在x3005的指令有条件地跳转到x300E,开始输出计数器的值。如果R4不为零,那么R1里的字符是合法的,需要被检查。在x3006,x3007,x3008的一组指令判断R1和R0的内容是否相同。这组指令执行了以下的操作:R0+(NOT(R1)+1)只有在R1和R0的二进制数完全相同的条件下,上述表达式才会为零。如果二进制数不相同,在x3009的条件分支指令会跳转到x300B,也就是说,跳过了用与增加计数器R2的x300A中的指令。x300B的指令递增R3,这样它就指向被检查的文档中的下一个字符,在x300C的指令把这个字符加载到R1里,然后在x300D的指令无条件跳转回x3004,重新开始字符处理的过程。当标记(这里指EOT)终于被检测到时,输出计数器的过程开始(在x300E)。x300E的指令把00110000加载入R0,之后在x300F的指令把R0的值加上计数器的值。这样就把计数器的二进制表示(存储于R2中)转换成了ASCII码表示(存储于R0)。在x3010的指令向操作系统调用一个TRAP指令把R0的内容输出到屏幕上。当这个调用完成后,程序继续运行,在x3011的指令调用一个TRAP指令来结束程序。5.6 数据通路重提在结束第五章之前,让我们回顾一下我们在第三章时第一次见到的数据通路(图3.33)。现在我们准备检查所有运行LC-3 ISA所需要的结构,在本章前面的图5.4,5.5,5.6,5.7,5.8,5.9和5.11中,我们已经看到了其中的许多结构。我们重新描绘了这个结构如图5.18。注意在数据通路里有两种箭头,实心箭头和空心箭头。实心用于表示被处理的信息,空心表示控制信号。控制信号从标有“控制(Control)”的方块输出。图5.18中,从“控制”到大多数的控制信号的连线已经被省略,以减少不必要的混乱。5.6.1 数据通路的基本组成部分总线毫无疑问,你会注意到那个有两端都有箭头的粗黑线结构,它代表数据通路的总线。LC-3的总线由16根线和与之相关联的电子设备组成,它允许通过必要的总线上的电子设备的联系,将16位信息从一个结构传输到另一个结构。确切的说,在一个时间内在总线上只可传输一个值。注意:每一个提供数值给总线的结构在它的输入箭头后都有一个三角。这个三角(称为三态设备)允许计算机的控制逻辑一次只有一个提供者能提供信息给总线。希望获得数值的结构通过将LD.x(加载使能)信号设为1(回忆3.4.2节门控锁存器的讨论)得到信息。不是所有的计算机都有单独的总线。存储器计算机最重要的部件之一是包括指令和数据的存储器。存储器通过向存储器地址寄存器(MAR)加载地址而被访问。如果执行加载操作,控制信号就会读取存储器数据,结果将被传输到存储器数据寄存器(MDR)。另一方面,如果执行存储操作,要被存储的数据首先被存入MDR。然后控制信号指定WE被设为1,使之被存进存储单元。ALU和寄存器堆ALU
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 文化外交中的身份认同研究-洞察及研究
- 2025年农业绿色发展政策与农业废弃物资源化利用技术专利分析报告
- 家庭农场联合经营合作协议方案
- 四年级数学(三位数乘两位数)计算题专项练习及答案
- 数据加密传输研究-洞察及研究
- 重难点解析广东省四会市中考数学真题分类(平行线的证明)汇编章节测评试卷(含答案详解版)
- 2025年企业可持续发展报告:SDGs视角下的绿色生产与消费模式
- 重难点自考专业(学前教育)真题含答案(夺分金卷)
- 重难点解析人教版8年级数学下册《平行四边形》综合训练试卷(含答案详解)
- 环境治理数字化转型-洞察及研究
- DBJ41T 137-2014 防渗墙质量无损检测技术规程
- 百岁居区域+乐活内外勤宣导材料
- 内蒙古职工考勤管理制度
- GB/T 21220-2024软磁金属材料
- 《数字媒体技术导论》全套教学课件
- 吉林大学介绍
- 卫浴设备安装技能的培训与认证
- NB-T+10488-2021水电工程砂石加工系统设计规范
- 废气处理工程协议
- SH/T 3158-2024 石油化工管壳式余热锅炉(正式版)
- QCSG1204009-2015电力监控系统安全防护技术规范
评论
0/150
提交评论