3.1 概述3.2 计算机硬件的操作3.3 计算机硬件的操作数3.4 指令的计算机内部表示3.5 决策指令3.6 计算机硬件对过程的支持3.7 计算机对字符的处理(略去)3.8 MIPS的其他寻址方式第三章指令系统3.1 概述概述要给计算机硬件直接下命令,就必须使用机器的语言机器语言中的“单词”称为指令指令,其“词汇表”称为指令集指令集本章将介绍现实中计算机所使用的指令集系统通过学习机器指令,你会了解到计算机中的一个重要概念:存储程序(存储程序(storedstored- -rogramrogram))着重介绍的是MIPS指令集 ,涉及到MIPS指令的操作数、指令格式及指令类别1、、CISC---复杂指令系统计算机复杂指令系统计算机Complex Instruction Set Computer,20世纪60年代后期,随着IC、LSI、VLSI的出现和发展,计算机硬件成本不断下降,人们热衷于在指令系统真增加更多的指令和复杂的指令,来提高操作系统的效率,促使指令系统越来越复杂,这一时期的计算机称为CISC。
2、、RISC---精简指令系统计算机精简指令系统计算机Reduced Instruction Set Computer ,1975年IBM公司开始研究指令系统的合理性问题,IBM的John Cocke提出精简指令的想法,本书作者David A. Patterson创造了RISC一词,并定义了其含义,后来John L. Hennessy带领他在斯坦福的研究小组研制成功MIPS机,精简指令系统计算机从此诞生并发展起来一、指令系统的发展二、二、RISC的特点的特点1、优先选取一些使用频率最高的简单指令,以及一些很有用但不复杂的指令,避免复杂指令2、指令长度固定,指令格式种类少,寻址方式种类少,指令各字段的划分比较一致,各字段功能较规整3、只有存数、取数指令访问存储器,其余指令的操作都在寄存器之间进行4、CPU中通用寄存器数量较多三、三、MIPS简介简介1、处理器的缩写、处理器的缩写① Million Instruction Per Second,泛指每秒能执行百万条指令的处理器② Microprocessor without Interlocking Pipeline Stage,一种无内锁的流水线微处理器2、、MIPS公司公司3.2 计算机硬件的操作指令计算机硬件的操作指令一、指令的基本格式一、指令的基本格式指令格式,是指令用二进制代码表示的结构形式,通常有操作码字段和地址码字段组成。
操作码表示指令的操作特性和功能,而地址码通常指定参与操作的操作数的地址,故指令基本格式如下:OPA1、操作码、操作码操作码字段的位数取决于指令系统的规模,例如,只有8条指令的指令系统,OP字段有3位就够了,如果系统包含32条指令,则OP字段需要5位操作码一般来说一个包含n位的操作码能够表示2n条指令2、地址码、地址码根据一条指令中有几个操作数地址,可将该指令称为几地址指令,一般有三地址指令、二地址指令、一地址指令和零地址指令格式:OPAOPA2A1OPA2A1A3OP1、加法指令add rd, rs, rt #add rd, rs, rt #注释注释①每条指令只执行一个操作,并且有且只有三个变量②书写时,每一行只有一条指令,注释放在行尾,由#号引出③该指令执行rd=rs+rt的操作例如:add a, b, c # b + c的和存放在a中其中 add称操作符, 表示加运算;紧跟add的a是目的操作数, 即为结果,其余b、c表示源操作数每条指令中由 “#”号领头的部分是注释三、三、MIPS算术运算指令算术运算指令例如:计算 a=b+c+d+e;add a,b,c # b + c的和存放在a中add a,a,d # b + c + d的和已存放在a中add a,a,e # b + c + d + e的和已存放在a中2、减法指令sub rd, rs, rt #注释例例3.1把两个把两个C语言赋值语句编译成语言赋值语句编译成MIPS汇编指令汇编指令下面这段C语言代码包含5个变量a, b, c, d, e:a = b + c;d = a – e;【【解答解答】】add a, b, c # a=b+csub d, a, e # d = a – e例例3 3. .2 2把一个复杂的把一个复杂的C C语言赋值语句编译成语言赋值语句编译成MIPSMIPS汇汇编指令编指令f f = = (g(g + + h)h) – (i(i + + j)j); ;【【解答解答】】addaddt t0 0, , g,g, h h# 临时变量t0=g + h的和addaddt t1 1, , i,i, j j# 临时变量t1=i + j的和最后做减法,把差放在f中:subsubf,f, t t0 0, , t t1 1# f=t0 - t1的值完成一个类似于加法的操作需要3个操作数:2个数参与运算,1个数存放结果。
每条指令刚好包含3个操作数,不多也不少,这是遵循简化硬件的原则,因为操作数的个数不定的硬件实现比个数固定的硬件实现复杂得多这就是硬件设计要考虑的第一条原则:设计原则设计原则1:简单性来自规则性简单性来自规则性Simplicity favors regularity. ))3.3计算机硬件的操作数计算机硬件的操作数cpu的的寄存器(寄存器(register)) 中中---寄存器操作数寄存器操作数寄存器是建造计算机的基石,因为它们是硬件设计中用到的基本单元,对于程序员也是可见的,但其数量有限计算机硬件的操作数放在什么地方?存储器中存储器中---存储器操作数存储器操作数复杂数据结构,如数组、结构体等包含大量数据元素,不可能映射到数量有限的寄存器上,只能存储到存储器中指令中指令中---立即数立即数有些操作数直接与指令存放在一起,称为立即数,而MIPS中专门设置有一些立即数指令,如addi,slti等一、一、MIPS的寄存器的寄存器在MIPS体系结构中,一个寄存器的长度是32位;又称32位为字长MIPS体系中的数据字、指令字都是32位MIPS寄存器汇编符号记为$s0、$s1、 $s2、$s3 …$s7,对应编码为:16、17、… 23; 以及$t0、$t1、 $t2、$t3 …$t7,对应编码为:8、9、… 15。
寄存器和编程语言的变量的一个主要区别是,寄存器数量有限,现在的计算机中一般是32个MIPS也只有32个寄存器为什么限于32个寄存器?原因可以从硬件设计的第二条原则找到:设计原则设计原则2 2::越小越快越小越快Smaller is faster. ))寄存器的数量如果很大,则电信号需要传输的距离更长,因而时钟周期也会变得很长例例3.3 3.3 使用寄存器编译使用寄存器编译C C语言赋值语句语言赋值语句以上例C语言赋值语句为例:f = (g + h) – (i + j);为变量f, g, h, i, j分别指定寄存器$s0, $s1, $s2,$s3, $s4 而临时变量指定寄存器$t0,$t1,则MIPS 汇编符号指令:addadd$ $t t0 0, , $ $s s1 1, , $ $s s2 2# 寄存器$t0中包含g + h的和addadd$ $t t1 1, , $ $s s3 3, , $ $s s4 4# 寄存器$t1中包含i + j的和subsub$ $s s0 0, , $ $t t0 0, , $ $t t1 1# $t0 - $t1的差放入f中硬件硬件/软件接口软件接口 编译器不仅把变量同寄存器联系起来,还为数组和结构这样的数据结构分配内存空间。
这样,编译器就能把恰当的基地址放入数据传送指令中二、操作数在内存单元中二、操作数在内存单元中计算机如何表示和存取数组这样的复杂数据结构呢?处理器只能在寄存器中保存很少的数据,而内存则可以存放数以百万计的数据单元因此,数组这样的数据结构存放在数组这样的数据结构存放在内存中内存中内存单元用地址编号表示内存单元用地址编号表示, ,叫内存地址叫内存地址 ,例例:实际MIPS内存地址:一个字=4字节表示,按字节编址:字节寻址还影响数组的索引要得到正确的地址,加到基址上的偏移量应该乘以4三、数据传送指令三、数据传送指令 : LW与与 SW1 1、取字指令(、取字指令(Load Word))LW指令格式: Lw rt, offset(rs)Lw rt, offset(rs)#注释① offset为偏移量,是数组首地址到数组中某元素存储位置的字节偏移量,是一个常数② rs是存储数组首地址的寄存器,称为基址寄存器③ rt为目的操作数寄存器,存放取自【(rs)+offset】的数据注意:offset(rt)表示存放数据的内存单元地址,即内存地址即内存地址例例3.4 3.4 编译有一个操作数在内存中的编译有一个操作数在内存中的C C语言赋值语句语言赋值语句: :g = h + A[8];g = h + A[8]; 设数组A[100]【【解答解答】】操作数A[8]在内存中,首先得把它转移到寄存器中。
它的地址是数组A的基地址加上8*4的和 假设$s3存放数组A的基地址,g对应$s1寄存器,h对应$s2寄存器lwlw$ $t t0 0, , 3232( ($ $s s3 3) )# 临时寄存器$t0存放A[8]的值addadd$ $s s1 1, , $ $s s2 2, , $ $t t0 0# g = h + A[8]数据传送指令中的常量称为偏移量偏移量((offsetoffset)),用来计算地址的寄存器称为基地址寄存器基地址寄存器((basebase registerregister))内存有效地址内存有效地址EA=offset(EA=offset(偏移量偏移量)+ + rs(基地址寄存器基地址寄存器)2 2、存字指令(、存字指令(Store Word))SWSW例例3.53.5使用取指令和存储指令进行编译使用取指令和存储指令进行编译 :C语句: A[12] = h + A[8];指令格式: sw rt, offset(rs) #注释指令功能:将rt寄存器中的数据存入【(rs)+offset】内存单元注意事项:同lw指令【【解答解答】】首先应该使用lw指令将A[8]取到寄存器中,再做加法运算,最后利用sw指令将和存入A[12]。
假设变量h在$s2寄存器中,数组A的基址在$s3中,则该C语句的MIPS汇编指令代码如下:lw w$ $t t0 0, , 3232( ($ $s s3 3) )# 临时寄存器$t0存放A[8]的值addadd$ $t t0 0, , $ $s s2 2, , $ $t t0 0# 临时寄存器$t0存放h+A[8]的值swsw$ $t t0 0, , 4848( ($ $s s3 3) )# 把h+A[8]的值存储到A[12]中例例3.6 使用可变数组下标进行编译使用可变数组下标进行编译假设A是100个元素的数组,基地址在寄存器$s3中,变量g, h, i分别和寄存器$s1,$s2,$s4相联系写出下面的C语句的MIPS汇编代码:g g = = h h + + A[i]A[i]【【解答解答】】为了能从A[i]中取出数据,首先要得到A[i]的内存地址,且必须以offset(rs)的形式体现通过计算A+4*i可得A[i]的内存地址,将其放入基址寄存器,这样只要令偏移量offset为0,即可以offset(rs)的形式实现取数指令:add $t1, $s4, $s4# 临时寄存器$t1 = 2 * iadd $t1, $t1, $t1# 临时寄存器$t1 = 4 * iadd $t1, $t1, $s3# 临时寄存器$t1 = A[i]的地址(4*i+$s3)然后把A[i]取到临时寄存器中:lw $t0, 0($t1)# 临时寄存器$t0 = A[i]最后把A[i]和h加起来,放到变量g中:add $s1, $s2, $t0# g = h + A[i]四、软硬件接口:溢出(四、软硬件接口:溢出(spilling)寄存器)寄存器很多程序中变量的数量比寄存器的数量多。
因此,编译器尽量把使用最频繁的变量保持在寄存器中,而把其余的放在内存中,并用取数和存储指令在寄存器和内存之间传送数据将不常用或是以后才用到的变量存入内存的过程称为溢出溢出((spilling))寄存器寄存器五、小结五、小结P83 图3—4,指令与操作数小结3.4 指令的计算机内部表示指令的计算机内部表示在计算机内部,指令体现为二进制数,由连续的0,1串组成,计算机为了识别指令,会将这个32位的二进制数分成几个字段,用来表示不同的信息,如表示操作码、寄存器号等机器指令格式以二进制表示:000000100011001001000000001000006位5位5位5位5位6位计算机如何识别和解释指令呢?首先要了解机器指令的表示MIPS汇编指令如下所示: add $t0, $s1, $s2二进制表示为:00000010001100100100000000100000一、一、 R型指令格式型指令格式这些字段的意义是:opop:指令的操作码,传统上称为opcodeopcode,此处为0rsrs:表示第1个源操作数的寄存器rtrt:表示第2个源操作数的寄存器rdrd:表示目的操作数的寄存器,用来保存操作的结果。
shamtshamt:移位位数,移位指令用作移位次数控制functfunct:功能域,用来选择opop域的一个特定的操作有时称为函数码((functionfunction codecode))R R型(型(R R- -type or Rtype or R- -formatformat)指令)指令,其中其中R R代表寄存器代表寄存器(Register(Register),),意为意为操作数都在寄存器中操作数都在寄存器中oprsrtrdshamtshamtfunctfunct6位5位5位5位5位6位31…….26 25……….21 20………..16 15……..11 10………6 5………….0以上的R型指令非常适合运算类的指令,但当用于存、取数指令时,如果偏移地址使用5位字段,则偏移的范围就表达的太小了,并不适用因此,一方面要使所有指令长度都相同,另一方面又要让每条指令的格式都合适,产生了矛盾,因而提出了硬件设计的第三个原则:好的设计需要合适的折衷好的设计需要合适的折衷Good design demands good compromises. 由此进行折衷,设计出适合数据传送类指令的I型指令格式。
例题:写出指令例题:写出指令add $t0, $s1, $s2 的机器代码的机器代码0171880 03232二、二、I I型指令格式型指令格式 (Immadiate(Immadiate----Type)Type)各字段含义如下:op字段:操作码字段,35表示取数指令lw,43表示存数指令swrs字段:基址字段,存放基址寄存器号rt 字段:取指令的目的操作数寄存器号或存指令的源寄存器号offset字段:偏移量字段,指定相对于基址rs的字节偏移量16位的偏移量意味着存、取数指令可以装入的字的地址范围是,以位的偏移量意味着存、取数指令可以装入的字的地址范围是,以rs中的基地址为中心,中的基地址为中心,±±215(即(即32,768)个字节的范围,也即)个字节的范围,也即±±213(即(即8192)个字的范围个字的范围oprsrtoffset6位5位5位16位31…….26 25……….21 20……….16 15…………………………………….0分析下列取数指令的机器代码:lw$t0, 32($s3)# 临时寄存器$t0存放A[8]的值Op=4319832注意:在取指令lw中,rt字段指定的是目的操作数寄存器。
这里,$s3(寄存器号19)放在rs域中,$t0(寄存器号8)放在rt域中,偏移量32放在offset域中 该指令用十进制数表示的格式为:MIPS指令的编码注意:n.a.即not applicable,表示在这条指令中无此字段例例3.7 将将MIPS汇编语言翻译成机器语言汇编语言翻译成机器语言写出写出C语句:语句:A[A[300300] ] = = h h + + A[A[300300] ]的机器语言代码的机器语言代码解答解答】】假设数组A的基地址在$t1中,变量h对应于寄存器$s2,则C赋值语句编译后的MIPS汇编代码如下:lw $t0, 1200($t1)# 临时寄存器$t0存放A[300]的值add $t0, $s2, $t0# 临时寄存器$t0存放h+A[300]的值sw $t0, 1200($t1)# 将h+A[300]的值存回A[300]中然后再写出这3条指令的MIPS机器语言代码为了方便起见,先用十进制数来表示机器指令根据前页表3.1,可得出下面的机器指令:A[300]=h+A[300];lw $t0, 1200($t1)add $t0, $s2, $t0sw $t0, 1200($t1)四、存储程序(四、存储程序(storedstored- -programprogram))的概念。
计算机的两个重要原理:1.指令是以数的形式表示的指令是以数的形式表示的2.程序可以存放在内存中程序可以存放在内存中,,像数字一样被读写像数字一样被读写三、小结:三、小结: P87 图图3—6 3.5 决策指令决策指令计算机区别于简单的计算器之处就在于它的决策能力基于输入数据和计算中产生的值的各种情况,执行的指令也可能不同在高级语言中一般用if语句代替决策,有时用带go to的if语句实现决策,MIPS中有类似功能的两种决策指令:一、分支指令(条件跳转指令)一、分支指令(条件跳转指令)1、beq指令指令格式:beq register1,register2,Label #注释指令功能:若register1=register2 则跳转到标号为Label的语句例3.8 将if语句编译成条件分支语句if (i==j) go to L1;f=g+h;L1: f=f-i;【解答】首先为变量f、g、h、i、j分配寄存器$s0---$s4第一条语句比较i、j是否相等,然后根据结果决定是否跳转到L1语句,这恰好可以编译成一条beq语句:beq $s3,$s4,L1 #如果i等于j则跳转到L1add $s0, $s1, $s2 #f = g + h (如果i等于j则该 指令被跳过)L1: sub $s0, $s0, $s3 #f = f - i (该指令总是要执行)2、bne指令指令格式:bne register1,register2,Label #注释指令功能:若register1≠register2 则跳转到标号为Label的语句例3.9 将if-then-else语句编译成条件转移指令if (i==j) f=g+h;else f=g-h;【解答解答】bne $s3, $s4, Else#如果i ≠ j则跳转到Elseadd $s0, $s1, $s2#f = g + h(如果i ≠ j则该指令被跳过)j Exit#跳转到ExitElse: sub $s0, $s1, $s2#f = g - h (如果i = j 则跳过该指令)Exit:3、beq与bne指令的机器指令格式由于beq与bne指令中包含了跳转位置与当前指令的字偏移量,故采用I型指令格式更为合适:4/5rsrtLabel6位5位5位16位31…….26 25……….21 20……….16 15…………………………………….0其中,beq指令的op值为4,bne指令的op值为5,rs、rt两寄存器指定进行比较的两个数据,Label表示当前指令的下一条指令地址与跳转目标地址之间的字偏移量字偏移量,可正可负。
需要注意的是,本来程序顺序执行,遇到beq/bne指令后,一旦发生跳转,则PC寄存器的内容会被修改,由原来的PC+4修改为PC+4+Label*4,即:需要将标号左移2位二、无条件跳转指令二、无条件跳转指令指令格式:j Label #注释指令功能: 无条件跳转到标号为Label的语句机器格式:2Label6位26位31…….26 25………..……………………..…………………………………….0其中,Label表示跳转目标地址的26位字地址,但内存地址均为32位,故此26为字地址需要左移2位后形成28位字节地址,所以用当前PC寄存器的高4位与这个28位字节地址拼接形成一个32位内存地址,写入PC,以实现跳转三、循环结构的实现三、循环结构的实现决策指令在if语句和循环结构的实现中都起着重要的作用,在分支结构中用于二者选一;在循环结构中用于重复执行在这两种情况下,关于决策的汇编指令是相同的,即高级语言中的if语句和while语句都是由决策指令beq和bne来实现的例3.10 编译一个带有可变数组下标的循环Loop: g=g+A[i];i=i+j;if(i!=h) go to Loop写出该循环的MIPS汇编代码【解答解答】假设A是100个元素的数组,数组A的基地址在$s5中,变量g, h, i, j分别对应于寄存器$s1, $s2, $s3, $s4。
首先将A[i]取出放入临时寄存器$t0Loop: add $t1, $s3, $s3 # 临时寄存器$t1 = 2 * iadd $t1, $t1, $t1 # 临时寄存器$t1 = 4 * iadd $t1, $t1, $s5 # $t1 = address of A[i]lw $t0, 0($t1) # 临时寄存器$t0 = A[i] 下面两条指令把A[i]加到g中,j加到i中:add $s1, $s1, $t0 # g = g + A[i]add $s3, $s3, $s4 # i = i + jbne $s3, $s2, Loop # 如果i ≠ h则跳转到Loop例例3.11 3.11 编译编译whilewhile循环循环while ( save[i] = = k )i = i + j;写出这段C程序的MIPS汇编代码解答解答】假设i, j, k分别对应于寄存器$s3, $s4, $s5,数组save的基地址在$s6中写出该循环的MIPS汇编代码程序员一般不使用go to语句实现循环,传统的循环结构是用while语句来实现的,可通过编译器来翻译。
Loop: add $t1, $s3, $s3 # 临时寄存器$t1 = 2 * iadd $t1, $t1, $t1 # 临时寄存器$t1 = 4 * iadd $t1, $t1, $s6 # $t1 = address of save[i]lw $t0, 0($t1) # 临时寄存器$t0 = save[i]bne $t0, $s5, Exit # 如果save[i]≠k则结束循环add $s3, $s3, $s4 # i = i + j j Loop # 跳转到LoopExit: ……作业:P150 习题3.9 优化此程序段四、小于时置四、小于时置1 1 指令指令: sltslt指令格式:slt rd, rs, rt #注释,R型指令指令功能:对rs、rt两个寄存器进行比较,若rs