当前位置: 首页 > article >正文

MIPS指令集(一)基本操作

目录

计算机硬件的操作数

存储器操作数

常数或立即数操作数

有符号数和无符号数

指令的格式

   逻辑操作

决策指令

循环


计算机硬件的操作数

先从一条C语句入手

a = b + c;

将其翻译为MIPS

add a, b, c

其中a,b,c就是这条指令的操作数。表示将b与c的和放入a中。

加法指令只有三个操作数,也就是说只能一次完成两个数相加,下面的指令序列会完成四个数相加

add a, b, c
add a, a, d
add a, a, e

只能一次完成两个数相加体现了硬件简单性的设计原则。下面会知道,使用指令实际上不会写诸如a,b,c之类的字符,而是使用寄存器。

与高级语言不同,MIPS的算术运算被要求操作数只能来自寄存器。寄存器是构成计算机的基本单元。在MIPS体系结构中寄存器大小为32位,同时拥有32个寄存器。在MIPS体系结构中也常把32位称作一个(word)。

MIPS在使用寄存器时,用'$'后跟两个字符表示寄存器。用$s0,$s1...表示类似C语言中的变量所对应的寄存器,用$t0,$t1...表示临时变量对应的寄存器。

a = (b + c) - (d + e)

以该C赋值语句为例,将其翻译为MIPS指令,假设s0,...s4分别对应存储了a,..e

add $t0, $s1, $s2 #b+c的结果存在临时变量寄存器t0中
add $t1, $s3, $s4 #同上
add $s0, $t0, $t1

MIPS中#后是注释,注意这种语言一行只有一条指令,且注释是在一行的末尾结束

存储器操作数

高级语言中常有数组和结构体,而且往往大小不止一个字,这种数据结构就会存储在内存中,而内存就是存储器,磁盘更习惯叫做io设备。

由于MIPS算术指令只能操作寄存器,因此必须有一种手段,能将内存中的数据加载到寄存器中。

这些指令叫做数据传输指令

为了访问内存中的字,必须给出地址。内存中的地址是按字节编排的,也就是说每个相邻的地址相差1

图中每一块大小一个字节。

将数据从内存加载到寄存器通常称为取数(load)指令,实际MIPS取数指令助记符是lw,操作数有三个,第一个表示要把数据存到哪个寄存器,第二个是地址偏移量(单位为字节,要求是常数),第三个是基址寄存器

a = b + A[8];

假设a存在s0,b存在s1,A地址存在s2。

lw $t0, 32($s2) #一个字大小为32位,也就是4字节,8个字就得偏移32字节
add $s0, $s1, $t0

MIPS字的起始地址是4的倍数,这叫做对齐限制。字在内存中如图存储。

      

MIPS还有一类指令是将寄存器中的数据复制到存储器中,叫做存数(store)指令。MIPS记作sw,用法与lw类似,只是第一个操作数代表要从哪个寄存器中得到数据。

常数或立即数操作数

仅仅从已经介绍的指令来看,要使用常数,只能从存储器取出(lw),如要将a+4

lw $t0, AddrConstant($s1)#AddrConstant为某一常数偏移量,将4加载到t0
add $s0, $s0, $t0

如果要避免使用取数指令,可使用addi指令

addi $s0, $s0, 4

像这种加法叫加立即数(add immediate),常数操作数出现频率高,像这种带立即数的指令,比从存储器种取值快很多,能耗也较低。

常数0可简化指令集。例如,数据传输指令可视为操作数为0的加法。MIPS将$zero恒置为0,编号也为0

有符号数和无符号数

有符号数在MIPS中用补码表示。需要注意的是,当不满32位的数被存储时,高位会补上符号位。

像0100,存在寄存器中

00000000 00000000 00000000 00000100

1100,存在寄存器中

11111111 11111111 11111111 11111100

MIPS有一些末尾为u的指令操作无符号数,具体后面可以见到。

指令的格式

指令以二进制的形式存储,现在我们可以把指令翻译成二进制。

所有的寄存器会被映射为数字,$s0~$s7映射到16~23, $t0~$t7映射到8~15。

add $t0, $s1, $s2

以该指令为例,先将其翻译为十进制,再转为二进制。

 

机器指令分为多个字段,本例第一个和最后一个告诉MIPS计算机要执行加法操作,第二个和第三个表示源操作数寄存器,第四个字段表示存放结果的寄存器,第五个字段没有用到,故置为0。

截取《计算机组成与设计 硬件/软件接口》中相关说明

这种指令格式在某些场景可能不适用,如lw指令需要传入偏移量,5位是不够用的,这时,想要增加位数,但是MIPS的设计是,所有指令的长度都相同,这样,就会采取折中方案:所有指令长度相同,但不同类型指令采用不同指令格式。如上述指令就是R型。另一种是I型,用于传输立即数。

在这种I型格式中,立即数大小仍然有限制。可以看到这种格式下,很难增加寄存器的数量,因为寄存器序号会使得rs,rt字段增加位。

   逻辑操作

一张图即可解决,用法也与其他指令类似。

决策指令

计算机的运算能力强大,但计算机与计算器的差别在于计算机能执行决策指令,也就是条件分支指令。MIPS有两条类似C语言 if和 go to的指令

beq regsiter1, register2, L1

表示若寄存器register1 和register2的值相等,跳转到L1标签。beq(branch if equal),相等则分支。

bne regsiter1, register2, L1

表示若寄存器register1 和register2的值不等,跳转到L1标签。bne(branch if not equal),不等则分支。

还需介绍另一种分支指令——无条件分支

j L1

j为jump的缩写

if (i == j) 
    f = g + h;
else
    f = g - h;

现在将该C语句编译为MIPS指令。

假设i存在s0,j存在s1,f,g,h分别存在s2,s3,s4

bne $s0, $s1, Else
add $s2, $s3, $s4
j Exit
Else: sub $s2, $s3, $s4
Exit:

循环

条件分支指令可以实现循环

while (save[i] == k)
    i += 1;

假设i和k存在s3和s5中,save的基址存在s6中。

Loop: sll $t1, $s3, 2 #需要将i×4
add $t1, $s6, $t1
lw $t0, 0($t1)        #要求偏移量为常数
bne $t0, $s5, Exit
addi $s3, $s3, 1
j Loop
Exit:


http://www.kler.cn/a/441147.html

相关文章:

  • C语言练习(31)
  • 6.进程的使用方式
  • 【NLP251】意图识别 与 Seq2Seq
  • 基于Django的个人博客系统的设计与实现
  • 【性能优化专题系列】利用CompletableFuture优化多接口调用场景下的性能
  • 7. 马科维茨资产组合模型+金融研报AI长文本智能体(Qwen-Long)增强方案(理论+Python实战)
  • 每日算法Day08【删除字符串中的所有相邻重复项、逆波兰表达式求值、滑动窗口最大值、前 K 个高频元素】
  • iOS Delegate模式
  • 微信小程序跑腿平台的设计与实现
  • transformer学习笔记-自注意力机制(2)
  • 导致服务器数据包丢失的原因有哪些?
  • 用shell脚本来判断web服务是否运行(端口和进程两种方式)
  • 面试题整理2---Nginx 性能优化全方案
  • hive注释comment中文乱码解决
  • 前端成长之路:CSS复合选择器
  • 【DataSophon】DataSophon1.2.1服务组件开启 kerberos
  • 如何在电脑上控制手机?
  • Cloudlog 电台日志系统 request_form SQL注入漏洞复现
  • 《从零开始:轻松入门数据结构的世界》
  • 【深度学习】热力图绘制
  • 自动外呼机器人如何处理复杂的客户问题?
  • mac-m2安装mysql遇到的问题
  • flex 弹性布局 笔记
  • 一行一行出字的视频怎么做?简单的操作方法
  • Django基础之模板
  • 30、使用ESP8266跟SG90舵机制作四足蜘蛛机器人