首页 MIPS系统指令系统超详细

MIPS系统指令系统超详细

举报
开通vip

MIPS系统指令系统超详细 3.1 概述 3.2 计算机硬件的操作 3.3 计算机硬件的操作数 3.4 指令的计算机内部表示 3.5 决策指令 3.6 计算机硬件对过程的支持 3.7 计算机对字符的处理(略去) 3.8 MIPS的其他寻址方式 第三章 指令系统 3.1 概述 要给计算机硬件直接下命令,就必须使用机器 的语言。机器语言中的“单词”称为指令,其“词 汇表”称为指令集。本章将介绍现实中计算机...

MIPS系统指令系统超详细
3.1 概述 3.2 计算机硬件的操作 3.3 计算机硬件的操作数 3.4 指令的计算机内部 关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf 示 3.5 决策指令 3.6 计算机硬件对过程的支持 3.7 计算机对字符的处理(略去) 3.8 MIPS的其他寻址方式 第三章 指令系统 3.1 概述 要给计算机硬件直接下命令,就必须使用机器 的语言。机器语言中的“单词”称为指令,其“词 汇表”称为指令集。本章将介绍现实中计算机所使 用的指令集系统。 通过学习机器指令,你会了解到计算机中的 一个重要概念:存储程序(stored-rogram) 着重介绍的是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 计算机硬件的操作指令 一、指令的基本格式 指令格式,是指令用二进制代码表示的结构形式,通常有 操作码字段和地址码字段组成。操作码表示指令的操作特性和 功能,而地址码通常指定参与操作的操作数的地址,故指令基 本格式如下: OP A 1、操作码 操作码字段的位数取决于指令系统的规模,例如,只有8条 指令的指令系统,OP字段有3位就够了,如果系统包含32条指令, 则OP字段需要5位操作码。一般来说一个包含n位的操作码能够 表示2n条指令。 2、地址码 根据一条指令中有几个操作数地址,可将该指令称为几地 址指令,一般有三地址指令、二地址指令、一地址指令和零地 址指令格式: OP A OP A2A1 OP A2A1 A3 OP  1、加法指令 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+c sub d, a, e # d = a – e 例3.2 把一个复杂的C语言赋值语句编译成MIPS汇 编指令 f = (g + h) – (i + j); 【解答】 add t0, g, h # 临时变量t0=g + h的和 add t1, i, j # 临时变量t1=i + j的和 最后做减法,把差放在f中: sub f, t0, t1 # 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:越小越快。(Smaller is faster. ) 寄存器的数量如果很大,则电信号需要传输的距离更长, 因而时钟周期也会变得很长。 例3.3 使用寄存器编译C语言赋值语句 以上例C语言赋值语句为例: f = (g + h) – (i + j); 为变量f, g, h, i, j分别指定寄存器$s0, $s1, $s2, $s3, $s4 而临时变量指定寄存器$t0,$t1,则MIPS 汇编符号 指令 : add $t0, $s1, $s2 # 寄存器$t0中包含g + h的和 add $t1, $s3, $s4 # 寄存器$t1中包含i + j的和 sub $s0, $t0, $t1 # $t0 - $t1的差放入f中  硬件/软件接口 编译器不仅把变量同寄存器联系起来,还为数 组和结构这样的数据结构分配内存空间。这样,编译器就能 把恰当的基地址放入数据传送指令中。 二、操作数在内存单元中  计算机如何表示和存取数组这样的复杂数据结构呢?  处理器只能在寄存器中保存很少的数据,而内存则可以存放 数以百万计的数据单元。因此,数组这样的数据结构存放在 内存中。  内存单元用地址编号表示,叫内存地址 ,例: 实际MIPS内存地址:一个字=4字节表示,按字节编址: 字节寻址还影响数组的索引。要得到正确的地址,加到基 址上的偏移量应该乘以4。 三、数据传送指令 : LW与 SW 1、取字指令(Load Word)LW 指令格式: Lw rt, offset(rs) #注释 ① offset为偏移量,是数组首地址到数组中某元素存储位置的 字节偏移量,是一个常数。 ② rs是存储数组首地址的寄存器,称为基址寄存器 ③ rt为目的操作数寄存器,存放取自【(rs)+offset】的数据 注意:offset(rt)表示存放数据的内存单元地址,即内存地址。 例3.4 编译有一个操作数在内存中的C语言赋值语句: g = h + A[8]; 设数组A[100] 【解答】 操作数A[8]在内存中,首先得把它转移到寄存器中。它 的地址是数组A的基地址加上8*4的和。 假设$s3存放数组A的 基地址,g对应$s1寄存器,h对应$s2寄存器。 lw $t0, 32($s3) # 临时寄存器$t0存放A[8]的值 add $s1, $s2, $t0 # g = h + A[8] 数据传送指令中的常量称为偏移量(offset),用来计 算地址的寄存器称为基地址寄存器(base register)。 内存有效地址EA=offset(偏移量)+ rs(基地址寄存器) 2、存字指令(Store Word)SW 例3.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 $t0, 32($s3) # 临时寄存器$t0存放A[8]的值 add $t0, $s2, $t0 # 临时寄存器$t0存放h+A[8]的值 sw $t0, 48($s3) # 把h+A[8]的值存储到A[12]中 例3.6 使用可变数组下标进行编译 假设A是100个元素的数组,基地址在寄存器$s3中,变量g, h, i分别和寄存器$s1,$s2,$s4相联系。写出下面的C语句的 MIPS汇编代码: g = h + A[i] 【解答】 为了能从A[i]中取出数据,首先要得到A[i]的内存地址,且 必须以offset(rs)的形式体现。通过计算A+4*i可得A[i]的内存地 址,将其放入基址寄存器,这样只要令偏移量offset为0,即可 以offset(rs)的形式实现取数指令: add $t1, $s4, $s4 # 临时寄存器$t1 = 2 * i add $t1, $t1, $t1 # 临时寄存器$t1 = 4 * i add $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位的二进制数分成几 个字段,用来表示不同的信息,如表示操作码、寄存器号等。 机器指令格式以二进制表示: 000000 10001 10010 01000 00000 100000 6位 5位 5位 5位 5位 6位 计算机如何识别和解释指令呢?首先要了解机器指令的 表示。 MIPS汇编指令如下所示: add $t0, $s1, $s2 二进制表示为:00000010001100100100000000100000 一、 R型指令格式  这些字段的意义是: op:指令的操作码,传统上称为opcode,此处为0。 rs:表示第1个源操作数的寄存器。 rt:表示第2个源操作数的寄存器。 rd:表示目的操作数的寄存器,用来保存操作的结果。 shamt:移位位数,移位指令用作移位次数控制。 funct:功能域,用来选择op域的一个特定的操作。有时称为 函数码(function code)  R型(R-type or R-format)指令,其中R代表寄存器(Register), 意为操作数都在寄存器中。 op rs rt rd shamt funct 6位 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 的机器代码 0 17 18 8 0 32 二、I型指令格式 (Immadiate--Type)  各字段含义如下: op字段:操作码字段,35表示取数指令lw,43表示存数指令sw rs字段:基址字段,存放基址寄存器号 rt 字段:取指令的目的操作数寄存器号或存指令的源寄存器号。 offset字段:偏移量字段,指定相对于基址rs的字节偏移量。 16位的偏移量意味着存、取数指令可以装入的字的地址范围是,以rs 中的基地址为中心,±215(即32,768)个字节的范围,也即±213(即 8192)个字的范围。 op rs rt offset 6位 5位 5位 16位 31…….26 25……….21 20……….16 15…………………………………….0 分析下列取数指令的机器代码: lw $t0, 32($s3) # 临时寄存器$t0存放A[8]的值 Op=43 19 8 32 注意:在取指令lw中,rt字段指定的是目的操作数寄存器。 这里,$s3(寄存器号19)放在rs域中,$t0(寄存器号8)放在rt域 中,偏移量32放在offset域中。 该指令用十进制数表示的格式为: MIPS指令的编码 注意:n.a.即not applicable,表示在这条指令中无此字段。 例3.7 将MIPS汇编语言翻译成机器语言 写出C语句:A[300] = h + A[300]的机器语言代码。 【解答】 假设数组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, $t0 sw $t0, 1200($t1) 四、存储程序(stored-program)的概念。 计算机的两个重要原理: 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则跳转到L1 add $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则跳转到Else add $s0, $s1, $s2 # f = g + h(如果i ≠ j则该指令被跳过) j Exit # 跳转到Exit Else: sub $s0, $s1, $s2 # f = g - h (如果i = j 则跳过该指令) Exit: 3、beq与bne指令的机器指令格式 由于beq与bne指令中包含了跳转位置与当前指令的字偏 移量,故采用I型指令格式更为合适: 4/5 rs rt Label 6位 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的语句 机器格式: 2 Label 6位 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]取出放入临时寄存器$t0 Loop: add $t1, $s3, $s3 # 临时寄存器$t1 = 2 * i add $t1, $t1, $t1 # 临时寄存器$t1 = 4 * i add $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 + j bne $s3, $s2, Loop # 如果i ≠ h则跳转到Loop 例3.11 编译while循环 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 * i add $t1, $t1, $t1 # 临时寄存器$t1 = 4 * i add $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 # 跳转到Loop Exit: …… 作业:P150 习题3.9 优化此程序段 四、小于时置1 指令: slt 指令格式:slt rd, rs, rt #注释,R型指令 指令功能:对rs、rt两个寄存器进行比较,若rs= 4,则退出程序 K值合法( 0 ≤ k ≤ 3 ),将跳转地址A[K]取到$t0中: add $t1, $s5, $s5 # 临时寄存器$t1 = 2 * k add $t1, $t1, $t1 # 临时寄存器$t1 = 4 * k add $t1, $t1, $t4 # $t1 = address of JumpTable[k] lw $t0, 0($t1) # 临时寄存器$t0 = JumpTable[k] jr $t0 # 基于寄存器$t0进行跳转 各分支程序段: L0: add $s0, $s3, $s4 # k = 0时,f = i + j j Exit # 该case语句结束了,退出 L1: add $s0, $s1, $s2 # k = 1时,f = g + h j Exit # 该case语句结束了,退出 L2: sub $s0, $s1, $s2 # k = 2时,f = g - h j Exit # 该case语句结束了,退出 L3: sub $s0, $s3, $s4 # k = 3时,f = i - j Exit: # switch语句的出口 swith语句中的前3种情况的汇编代码是类似的,都是由一 个标号,一个执行case语句的指令,一个退出switch语句的跳 转指令所组成,最后一种情况,直接进入switch语句的出口。 六、小结 P95 图3—9 总结 初级经济法重点总结下载党员个人总结TXt高中句型全总结.doc高中句型全总结.doc理论力学知识点总结pdf MIPS汇编语言的各个组成部分,在MIPS指令中增加 了分支指令和跳转指令,并在一个寄存器中永久地固定了一 个很有价值的值:0 3.6 计算机硬件对过程的支持 子程序(subroutine),或称作过程( procedure),是程 序员使程序结构化的手段,它使程序易懂,代码可以重复使用。 在过程的执行中,程序必须遵循以下6个步骤: 1.把参数放在子程序能够存取的地方:参数传递 2.把控制权转交给子程序: 调用子程序 3.获取子程序所需的存储资源:保护寄存器等 4.执行所需的任务:执行子程序体 5.把结果的值放在子程序的主调程序能够存取的地方:返回结果 6.把控制权返回给主调程序:返回主程序 MIPS为子程序调用提供一些专用寄存器。 一、过程专用寄存器 1、$a0-$a3:4个用来传递参数的寄存器,a代表argument。 2、$v0-$v1:2个用来返回值的寄存器,v代表value。 3、$ra: 一个用来返回到主调程序调用点的返回地址寄 存器,ra代表return address。 4、$sp: 一个堆栈指针寄存器,用于指向栈顶位置,Sp代 表stack pointer 各寄存器编号见:P102 图3-13 二、与过程调用相关的指令 1、跳转并链接指令jal (jump-and-link),也称过程调用指令。 指令格式: jal 子程序入口标号 指令功能: 1)把该指令的下一条指令地址PC+4保存在$ra中; 2)跳转到子程序所在的地址,子程序入口地址送给PC。 机器格式: 3 Label 6位 26位 指令中的link表示一个地址或链接,指向调用点以便子过程能正确 返回,该链接保存在$ra中,称为返回地址。 存储程序概念隐含这样一种思想:需要有一个寄存器来保存当前执 行的指令的地址。由于历史上的原因,在MIPS体系结构中,这个寄存 器通常称为程序计数器(program counter, PC)。尽管“指令地址 寄存器”这个名称可能更合理些 ,如IBM-PC计算机称作IP。 2、过程返回指令jr 指令格式: jr $ra #功能类似ret指令,过程的最后一条指令。 子程序参数传递方法: 1) 通过寄存器:主调程序(caller)把参数值放在$a0-$a3中,并 用指令jal X 跳转到子程序X,X是被调程序(callee)。X接着执 行其指令,把结果放在$v0-$v1中,然后把控制权返回给主调程序。 2) 通过堆栈:数据进入堆栈称为“压入”(push),数据离开堆栈称 为“弹出”(pop)。堆栈指针(stack pointer),其符号为$sp, 堆栈的栈顶地址比栈底地址低 ,把值压入栈中时,$sp的值就减小。 增加$sp的值则使堆栈收缩,从而把值从堆栈中弹出。 例3-14 编译一个非嵌套过程 int leaf_example ( int g, int h, int i, int j ) { int f; f = ( g + h ) - ( i + j); return f; } 【解答】 参数变量g, h, i, j分别对应于参数寄存器$a0, $a1, $a2, $a3。变量f对应于$s0。编译后的程序以该过程的标号为开头: leaf_example: #子程序名, 标号 将寄存器入堆栈进行保护: sub $sp, $sp, 12 # 调整堆栈,腾出空间保护寄存器 sw $s0, 8($sp) # 保存寄存器$s0以防破坏 sw $t0,4($sp) # 保存寄存器$t0以防破坏 sw $t1,0($sp) # 保存寄存器$t1以防破坏 下面3条指令对应于赋值语句f = (g+h ) - (i+j) : add $t0, $a0, $a1 # $t0 = g + h add $t1, $a2, $a3 # $t1 = i + j sub $s0, $t0, $t1 # f = $t0 - $t1 将计算结果放入返回寄存器$v0: add $v0, $s0, $zero # 返回f,($v0=$s0+0) 寄存器出栈恢复,并恢复堆栈指针: lw $t1, 0($sp) # 恢复寄存器$t1 lw $t0, 4($sp) # 恢复寄存器$t0 lw $s0, 8($sp) # 恢复寄存器$s0以备主调程序使用 add $sp, $sp,12 # 调整堆栈,收回堆栈空间 jr $ra # 返回调用程序 作业:P148 3.1 3.2 3.3 3.4 $t1, $t0, $s0保护进堆栈的堆栈变化状况  MIPS使用寄存器的约定: MIPS提供了两类寄存器: $t0-$t9:10个临时(temporary)寄存器,在子程序的调用中不 要保护。 $s0-$s7:8个需要保存的(saved)寄存器,在子程序的调用中必 须加以保护。 leaf_example: #子程序名, 标号 sub $sp, $sp, 4 # 调整堆栈,腾出空间保护寄存器 sw $s0, 0($sp) # 保存寄存器$s0以防破坏 add $t0, $a0, $a1 # $t0 = g + h add $t1, $a2, $a3 # $t1 = i + j sub $s0, $t0, $t1 # f = $t0 - $t1 add $v0, $s0, $zero # 返回f,($v0=$s0+0) lw $s0, 0($sp) # 恢复寄存器$s0以备主调程序使用 add $sp, $sp, 4 # 调整堆栈,收回堆栈空间 jr $ra # 返回调用程序 这样,例3-14就可以简化如下: 三、为新数据分配空间 过程中的一些大型数据结构如数组、结构体等通常保存 在堆栈中,除此之外,如果有超过四个参数需要传递到过程 中,则前4个参数放入$a0----$a3寄存器,后面的参数压入 堆栈,用$fp框架指针寻址。 P101 图3-12 硬件/软件接口(P102 图3-13) C语言中的变量是一个存储单元 , C语言有自动(automatic)和静态 (static)两种存储类别 ,为了简化对静态存储变量的存取,MIPS提 供了一个寄存器,称为全局指针(global pointer),其符号为$gp。 3.8 MIPS的其它寻址方式 很多时候,程序中需要对常数进行操作,而如果采用目 前所学过的指令,则需要先从内存中读取常数,然后才能使 用,而程序中有大量使用常数的指令,这样太复杂了,为了 提高效率,根据硬件设计的最后一个原则: 设计原则4:加快对常见情况的处理 Make the common case fast 引入能对常数直接进行操作的指令,即在算术指令中加入 常数字段,这样就比从存储器中读取要快得多。 一、立即数指令 1、加立即数指令addi 指令格式: addi rt, rs, imm #注释,I型指令 指令功能:rt=rs+imm 机器格式: 8 rs rt imm 31.… 26 25…….21 20…...16 15…………………………….0 例:addi $sp, $sp, 4 addi $sp, $sp, -4 2、小于立即数则置1指令slti 指令格式: slti rt, rs, imm #注释 指令功能:若rs<立即数imm,则rt寄存器置为1 机器格式: 10 rs rt imm 31.… 26 25…….21 20…...16 15…………………………….0 3、装入高位立即数指令lui 指令格式: lui rt, imm #注释 指令功能:将16位立即数imm送入rt寄存器的高16位,而rt 寄存器的低16位清零 机器格式: 15 0 rt imm 31.… 26 25…….21 20…...16 15…………………………….0 lui 把16位立即数装入寄存器高16位,而低16位清零. 硬件/软件接口: 不管是编译器还是汇编器都必须把大常数分割成 小常数,然后重新汇集到寄存器中。I型指令中immediate域的大小 限制,对于内存地址以及I型指令中常量的使用可能会有影响。如 果这一问题由汇编器来解决,那么汇编器需要一个临时寄存器来创 建大常量。这就是为汇编器保留寄存器$at的原因。 例3-15 加载一个32位的常数 怎样用MIPS指令把下面的32位常数装入$s0寄存器中? 0000 0000 0011 1101 0000 1001 0000 0000 【解答1】 首先用lui指令装入高16位: lui $s0, 61 然后用加法指令把低16位加到$s0中: addi $s0, $s0, 2304 【解答2】 addi指令会将16位立即数的最高位符号扩展到高16位中,因此应使 用ori指令配合生成32位常数 lui $s0, 61 ori $s0, $s0, 2304 二、分支和跳转指令的寻址 1、跳转指令的寻址:伪直接寻址(pseudodirect addresssing) j label 其跳转的目标地址由26位的label左移2位(乘4)后的 28位字节地址与PC中的高4位拼接形成。 2 2500 6位 26位 例3—16 下面的指令 j 10000 # 跳转到地址为10000的地方 经汇编后,机器码(以十进制表示)为: 指令执行后,跳转的目标地址为PC=PC[31--28]○2500*4: 2、分支指令的寻址:PC相对寻址 beq/bne rs, rt, label 其转移的目标地址是下条指令与目标指令之间的字节偏 移量与PC之和。 条件转移指令则不同,不仅有跳转地址,还要指定2个操 作数。下面的指令: bne $s0,$s1,Exit # 如果$s0≠$s1,则跳转到Exit 经汇编后,机器码(以十进制表示)为: 5 16 17 跳转地址偏移量 6位 5位 5位 16位 如果把程序的地址限于16位的域,则程序的指令数不能超 过216,这显然是太少了。MIPS的实际做法是,指定一个寄存器来 与地址域中的跳转地址相加,把和作为实际的跳转地址,可以用 下面的公式来计算: 程序计数器PC=PC寄存器的值 + 跳转地址偏移量*4 这样,程序的指令数可达232,从而解决了条件转移指令的跳 转地址大小问题。 这种方式的跳转寻址称为 PC 相 对 寻 址 ( PC-relative addressing)。 PC-relative addressing(PC ) PC PC+4 BNE $t1, $t2 , SKIP 低地 址 高地 址 -32768 PC相对寻址方式条件转移地址的计算公式 PC= (PC+4) +地址偏移x4 因为执行bne指令时, 取值操作已经完成,PC已经加了4, 所以新的PC值等于: PC+4。 例如: 100: bne $s0, $s1, Exit 104: add $t1, $t2, $t3 108:Exit: sub $t1, $t2, $t3 假设$s0≠$s1 ,那么指令执行后 PC=? 【解答】 如果 $s0≠$s1 则PC=104+(offset)x4=104+1x4=108 例3-17:展示机器语言中的转移地址偏移量 例3-11的while循环经编译后成为下面的MIPS汇编代码: Loop: add $t1, $s3, $s3 add $t1, $t1, $t1 add $t1, $t1, $s6 lw $t0, 0($t1) bne $t0, $s5, Exit add $s3, $s3, $s4 j Loop Exit: 假设该循环在内存中的起始地址为80000,写出其MIPS机器代码。 【解答】 机器代码及其地址如下: MIPS分支指令使用相对PC的字距离来寻址,所以第五行的bne 指令中的地址字段的值应该是2而不是8。最后的jump指令使用对应 于标号Loop的绝对字地址80000/4=20000。 2 20000 三、MIPS的寻址方式(addressing mode)总结 1.寄存器寻址(register addressing):操作数都在寄存器中。 2 基 地 址 寻 址 或 偏 移 量 寻 址 ( base or displacement addressing):有一个操作数在内存中,其地址是指令中的一 个寄存器和指令中常量的值之和。 3.立即数寻址(immediate addressing):有一个操作数是在指 令中的常量。 4.PC相对寻址(PC-relative addressing):地址是PC和指令中 常量*4的值之和。 5.伪直接寻址(pseudodirect addressing):地址是指令中的 26位地址*4,同PC的高4位连接起来的32位,也即32位字节地址。 四、机器语言的解码 例3-18 写出下面的机器指令对应的汇编语言: 【解答】 第一步是根据op域,确定这是什么指令。从表3.5可以查到, 31-26位为00000,该指令是R-format的指令。然后按照R型指令 格式把该机器指令重写一遍: op rs rt rd shamt funct 000000 00101 01111 10000 00000 100000 再判断具体是什么操作:5-0位为100000,正好是add指令。 最后看看其它域的值,rs、rt、rd的十进制值分别是5、15、 16,说明对应的寄存器分别是$a0、$t7、$s0。这时就可以写出 该机器指令对应的汇编指令:add $s0, $a0, $t7  本章小结 存储程序式的计算机的两条基本原理是,指令像数字一样表示, 程序在内存能象数据一样读写。指令集的设计,必须能够很好地平衡 执行程序所需指令数,每条指令所需时钟周期,以及时钟的速度这3 个因素。以下4条设计原则对于实现指令集的这种平衡起着指导作用: 1. 规整化简化硬件。(Simplicity favors regularity. )规整化促进了 MIPS指令集的以下特性的形成:保持所有指令的大小相同,在算术 指令中总是需要3个寄存器操作数,保持每种指令格式中的寄存器域 在同一位置。 2. 越小越快。(Smaller is faster. )对速度的要求正是MIPS选择32个 寄存器而不是更多的寄存器的原因。 3. 好的设计需要折衷考虑。( Good design demands good compromises. )在MIPS中的例子就是,在指令中提供更大的地址 和常量的要求,与保持所有指令的长度相同的要求之间的折衷。 4. 常见的情况要快。(Make the common case fast. )例如,在 MIPS中,条件转移指令使用PC相对寻址,常量操作数使用立即数寻 址。 3.9 程序的运行过程 运行程序的第一步是编译  高级语言程序比汇编语言程序所用代码行要少得多,从 而效率也高得多。但机器不能直接识别高级语言程序,它 需要编译器将把C程序转换成汇编语言程序,即机器能理解 的符号指令形式。  1975年前,很多操作系统和汇编器都是用汇编语言写的, 因为那时候的内存容量很小,编译器的效率也不高。如今 内存容量大大提高了,从而减少了对程序大小的限制;编 译器经优化后产生的汇编语言程序,可以比得上汇编语言 专家所写的程序,对于一些大程序,甚至比专家写的更好。 这使得高级语言和编译器得到了广泛的应用。 汇编: 汇编语言是计算机提供给高层软件的一 个接口  伪指令(pseudoinstruction),它们不需要在硬件上实现, 但汇编语言有了这些指令,可以简化编程和汇编的过程。  move $t0, $t1 # 寄存器$t0获得$t1的值(伪指令)  汇编器把它转换成与下面这条指令等价的机器语言:  add $t0, $zero, $t1 # 寄存器$t0获得0 + $t1的值  汇编器的主要任务是把汇编语言翻译成机器代码。它把汇 编语言的程序转换成目标文件(object file),该文件包括 机器语言指令、数据,以及把指令正确放在内存中所需的信 息。  汇编器还必须确定所有标号的地址。它把这些标号放在 一个符号表(symbol table)中,每个标号对应一个地址。 Unix系统的目标文件通常包括6个不同部分: 1. 目标文件报头(oject file header): 描述目标文件其它部 分的大小和位置。 2. 正文段(text segment):包含机器语言代码。 3. 数据段(data segment): 包含程序用到的数据,其中包括静态数据和动态数据。 4. 重定位信息(relocation information): 对取决于绝对地址的指令字和数据字进行标识,以便程序 装入内存中时进行重定位。 5. 符号表(symbol table): 包含没有定义的标号,如外部引用。 6. 调试信息(debugging information):对汇编模块的简单 描述,以便调试器可以把机器指令同C语言源文件联系起来,使数 据结构具有易读性。 3.9.3 链接目标代码  链接编辑器(link editor)或链接程序(linker),它把独立 汇编后产生的所有机器语言程序“缝合”在一起。  链接程序需要3个步骤来完成它的使命:  1. 把代码模块和数据模块放在内存中。  2. 确定数据和指令标号的地址。  3. 修正内部和外部的引用。  链接程序在每个目标模块中使用重定位信息和符号表来处理所 有未定义的标号,这些引用发生在branch指令、jump指令和数据 地址中。因此链接程序就如同一个编辑器,它找到旧的地址,并 用新地址来代替。使用链接程序的一个重要原因就是,修补代码 比重新编译和重新汇编要快得多。 堆栈指针初始化为7fff fffchex, 程序代码的起始地址为 00400000hex 静态数据起始地址为1000 0000hex 动态数据起始地址紧邻着静态数据, 向上增长 全局指针$gp被初始化为1000 8000, 以$gp为基地址, 使用16位偏移量(正负), 就可以存取 从1000 0000hex到1000 ffffhex的范围。 3.9.4 把程序装入内存中  经过前面3步,可执行文件还在磁盘上,操作系统把它读到内 存中,并启动程序。在Unix系统中如下6个步骤:  1. 读取可执行文件报头,确定正文和数据段的大小。  2. 为正文和数据创建一个足够大的地址空间。  3. 把可执行文件中的指令和数据复制到内存中。  4. 如果主程序有参数,则复制到内存中。  5. 初始化寄存器,把堆栈指针指向上面创建的空间中 第一个空闲位置。  6. 跳到一个启动例行程序,把参数复制到参数寄存器 中,调用程序的主程序。主程序返回时,启动例行程序用系 统调用exit来结束整个程序 3.10 综合程序范例  从C语言的两个子程序(交换数组元素的子程序swap和对数组 元素排序的子程序sort)来进一步介绍MIPS汇编代码的设计 方法。 C 子程序swap: swap ( int v[ ], int k ) { int temp; temp = v[k]; v[k] = v[k + 1]; v[k + 1] = temp; } 编写MIPS汇编代码一般遵循以下步骤: 1. 为子程序中的变量分配寄存器。 2. 为子程序体产生代码。 3. 保护寄存器,以免其内容在子程序调用之间受到破坏。 第一步:为swap子程序分配寄存器 由于swap只有两个参数——v和k,它们就分别放在参数寄存器 $a0和$a1中。只有一个临时变量,用$t1. 第二步:为swap子程序体产生代码 C语言中int型变量是4个字节长,MIPS是按字节寻址的,因此 索引k要乘以4再参与地址运算(在用汇编语言编程时,很多人往往 忘记这一点,这点需要加倍注意) 3.10.2 子程序sort  子程序sort,它对一个整数数组的元素进行排序。它要调用前面 的swap子程序。 sort ( int v[ ], int n ) { int i, j; for ( i = 0; i < n; i = i + 1 ) { for ( j = i - 1; j >= 0 && v[j] > v[j+1]; j = j - 1 )  swap ( v, j );  } } 3.11 数组和指针的比较  对使用数组及数组索引的汇编代码与使用指针的汇编代码进行比 较 ,便于理解指针的用法 和优点. clear1 ( int array[ ], int size );用数组下标编写清0 { int i; for ( i = 0; i < size; i = i + 1 ) array[i] = 0; } clear2 ( int *array, int size ); 用指针编写清0 { int *p; for ( p = &array[0]; p < &array[size]; p = p + 1 ) *p = 0; } loop1: add $t1, $t0, $t0 # $t1 = i * 2 add $t1, $t1, $t1 # $t1 = i * 4 add $t2, $a0, $t1 # $t2 = address of array[i] sw $zero, 0($t2) # array[i] = 0 addi $t0, $t0, 1 # i = i +1 slt $t3, $t0, $a1 # $t3 = (i < size) bne $t3, $zero, loop1 # 如果i < size则跳转到 到loop1 用指针: move $t0, $a0 # p = address of array[0] add $t1, $a1, $a1 # $t1 = size * 2 add $t1, $t1, $t1 # $t1 = size * 4 add $t2, $a0, $t1 # $t2 = address of array[size] loop2: sw $zero, 0($t0) # Memory[p] = 0 addi $t0, $t0, 4 # p = p + 4 slt $t3, $t0, $t2 # $t3 = (p < & array[size]) bne $t3, $zero, loop2 # $t3 = 1则跳转到loop2 两个子程序放在一起比较一下: 3.12 PowerPC和80x86的指令实例  1 IBM/Motorola PowerPC  PowerPC多出的两种寻址方式是:  1). 索引寻址(indexed addressing)  lw $t1, $a0 + $s3 # $t1 = Memory[$a0 + $s3]  2).更新寻址(update addressing)  lwu $t0, 4($s3) # $t0 = Memory[$s3 + 4]; $s3 = $s3 + 4  2 Intel 80x86  我们在这里介绍80x86系列的目的是让读者对世界上最流行的体 系结构的优点和缺点有所了解,而不是为了去写80x86的程序。  详见课文 3.13 指令集发展历史  1 累加器体系结构 : A = B + C;  2 通用寄存器体系结构 :  专用寄存器的通用化使得所有的寄存器都可用于任何目的的操作, 这样就产生了通用寄存器(general-purpose register)体系结 构。MIPS就属于这种类型。又分为二种:  (1)寄存器-内存型(register-memory, R-M(S))体系结构;  (2) 要求所有操作数都必须在寄存器中的装入-存储型(load- store)或寄存器-寄存器型(register-register, R-R)体系 结构 3 紧凑编码和堆栈体系结构  在内存不足的情况下,保持程序的短小是很重要的,因此像 Intel 80x86、IBM 360和VAX之类的机器都有变长指令,以匹 配变长的操作数,并使代码最小化。这种技术称为紧凑编码 (compact code)。Intel 80x86的指令的长度范围是1到17个 字节;IBM 360指令长度为2、4或6个字节;VAX指令长度可以 是1到54个字节之间的任一字节数。如果指令内存空间开始变 得宝贵,这样的技术可能又会流行起来。  4 高级语言计算机体系结构  Burroughs B5000是这种思想的商业源头,但如今它已没有 什么有显著影响的后代。一种计算机设计的思想,称为高级语 言 计 算 机 体 系 结 构 ( high-level-language computer architecture),其目标是使硬件更像编程语言。后来更高效 的编程语言和编译器的产生,加上内存的扩充,注定了它的失 败。 5 精简指令集计算机体系结构  面向语言的思想被精简指令集计算机(reduced instruction set computer,RISC)所取代。编程语言、编译技术和内存容量 的提高,使得需要在汇编级别做的事情更少了,因此指令集应该 通过编译器使用指令集的好坏程度来衡量,而不是通过汇编语言 程序员使用的好坏来衡量。  事实上从1982年以来,所有的新指令集都遵循RISC的思想:固 定指令长度,装入-存储型指令集,少量的寻址方式和少量的操 作。  RISC的实例有:MIPS, Sun SPARC, Hewlett-Packard PA-RISC, IBM PowerPC, 以及DEC Alpha。 3.14 本章小结  存储程序式的计算机的两条基本原理是,指令像数字一样表示, 程序在内存能象数据一样读写。指令集的设计,必须能够很好 地平衡执行程序所需指令数,每条指令所需时钟周期,以及时 钟的速度这3个因素。以下4条设计原则对于实现指令集的这种 平衡起着指导作用:  1. 规整化简化硬件。(Simplicity favors regularity. ) 规整化促进了MIPS指令集的以下特性的形成:保持所有指令的 大小相同,在算术指令中总是需要3个寄存器操作数,保持每种 指令格式中的寄存器域在同一位置。  2. 越小越快。(Smaller is faster. )对速度的要求正是 MIPS选择32个寄存器而不是更多的寄存器的原因。  3. 好的设计需要折衷考虑。(Good design demands good compromises. )在MIPS中的例子就是,在指令中提供 更大的地址和常量的要求,与保持所有指令的长度相同的要求 之间的折衷。  4. 常见的情况要快。(Make the common case fast. ) 例如,在MIPS中,条件转移指令使用PC相对寻址,常量操作 数使用立即数寻址。
本文档为【MIPS系统指令系统超详细】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
个人认证用户
豆浆
暂无简介~
格式:pdf
大小:1MB
软件:PDF阅读器
页数:98
分类:工学
上传时间:2019-05-17
浏览量:194