将陆续上传新书《自己动手写CPU》,今天是第46篇。

在MIPS32指令集中有两条特殊的存储载入指令:链接载入指令LL、条件存储指令SC,本次将介绍这两条指令。在兴许将实现这两条指令。

9.6 链接载入指令ll、条件存储指令sc说明

在本章前面的部分,笔者花费非常多笔墨介绍了OpenMIPS中除ll、sc之外的载入、存储指令的实现过程,本节至9.9节将专门介绍链接载入指令ll、条件存储指令sc的实现过程。ll、sc指令是MIPS32指令集架构中比較特殊的载入存储指令。用来实现信号量机制。

在多线程系统中,须要RMW(Read-Modify-Write)操作序列保证对某个资源的独占性,RMW操作序列的含义是,读取内存某个地址的数据。读取的数据经过改动。然后再保存回内存原地址。这个过程不能有不论什么打搅,因此须要建立一个临界区域(Critical Region),临界区域中完毕的操作通常称为原子操作。原子操作不被打搅。操作系统建立临界区域的方式一般是信号量机制,例如以下。

wait(semaphore);

原子操作;

 signal(semaphore);

semaphore是一个信号量。为1表示信号量使用中,为0表示信号量空暇。进行原子操作前,使用wait函数查询semaphore的值,假设为1,则等待,否则,将其置为1,開始运行原子操作,操作结束后,signal函数将semaphore置为0,这样其他线程就能够运行原子操作了。

须要注意的是,wait函数的运行也是一个原子操作。是一种“先检測后设置”操作(test-and-set operation),这样的操作一般不希望被外部设备中断,也不希望被其他线程打断。非常多处理器都有专门的指令用来实现“先检測后设置”操作,比方:680x0 CPU、x86 CPU等。这也是一种信号量机制。

MIPS32架构採用特殊的方式实现信号量机制。对于原子操作,MIPS32架构并不保证它一定是原子性的,也就是同意检測和设置在没有原子性保证的情况下执行。但仅仅在它确实原子的执行了的时候才让“设置”生效。MIPS32架构採用链接载入指令ll、条件存储指令sc来实现这样的信号量机制。

ll指令同一般的载入指令一样,从内存中载入一个字,可是,有一点不同。ll指令还会将处理器内部的一个链接状态位LLbit置为1,表明发生了一个链接载入操作。并将链接载入的地址保存到一个特殊寄存器LLAddr中(这个寄存器在多处理器中有作用,OpenMIPS是单处理器,所以在OpenMIPS实现过程中并没有实现LLAddr寄存器)。

ll指令运行完成后,会进行一定的操作(如:改动载入得到的数据)。然后运行sc指令,这能够觉得是一个RMW序列。有例如以下两种情况干扰这个RMW序列。受到干扰后。处理器会设置链接状态位LLbit为0。

  • 在ll、sc指令之间产生异常。从而进入异常处理例程。或者发生线程切换,导致RMW序列受到干扰。
  • 多处理器的系统中,还有一个CPU改写了RMW序列要操作的内存空间。

对于OpenMIPS而言,仅仅有第1种情况。

运行sc指令时。会对从ll指令開始的RMW序列进行检查。推断是否受到干扰,实际就是推断LLbit是否为1,假设没有受到不论什么干扰,LLbit保持为1。那么操作是原子的,sc指令会对ll指令载入数据的地址进行写回操作,并设置一个通用寄存器的值为1,表示成功,反之不进行写回操作。并设置一个通用寄存器的值为0,表示失败。

ll、sc指令的格式如图9-28所看到的。

从图中可知,能够根据指令码对这2条指令进行区分。

  • 当指令中的指令码为6'b110000时。是ll指令,链接载入指令

指令使用方法为:ll rt, offset(base)

指令作用为:从内存中指定的载入地址处,读取一个字节。然后符号扩展至32位,保存到地址为rt的通用寄存器中。

当中载入地址的计算方法例如以下。

载入地址 = signed_extended(offset) + GPR[base]

此外。还要设置链接状态位LLbit为1。

  • 当指令中的指令码为6'b111000时,是sc指令,条件存储指令

指令使用方法为:sc rt, offset(base)

指令作用为:假设RMW序列没有受到干扰,也就是LLbit为1,那么将地址为rt的通用寄存器的值保存到内存中指定的存储地址处,同一时候设置地址为rt的通用寄存器的值为1,设置LLbit为0。假设RMW序列受到了干扰,也就是LLbit为0,那么不改动内存,同一时候设置地址为rt的通用寄存器的值为0。当中存储地址的计算方法例如以下。

存储地址 = signed_extended(offset) + GPR[base]

以下通过一个样例体会ll、sc指令的作用,这个样例实现了上面介绍的wait函数。只是此处是使用ll、sc指令实现的。

wait:
ori $1, $0, sem // sem是信号量的地址,将这个地址赋给寄存器$1 TryAgain:
ll $2, 0($1) // 获取信号量的值,保存到寄存器$2
bne $2, $0, WaitForSem // 假设信号量被占用(其值为1),那么转移到地址WaitForSem
// 继续等待;假设信号量空暇(其值为0),那么运行以下的指令 nop
ori $2, $0, 1
sc $2, 0($1) // 假设没有被干扰,那么设置信号量被占用(将1保存到信号
// 量中)。同一时候,设置寄存器$2为1,反之,不改动信号量。
// 设置寄存器$2为0 beq $2, $0, TryAgain // 假设寄存器$2为0。表示ll、sc指令没有成功,未获取到
// 信号量。回到TryAgain继续尝试
nop jr $31 // 反之, 表示ll、sc指令成功,获取到信号量,能够进入
// “临界区域”了。调用wait函数时,会将返回地址放在
// 寄存器$31,所以此处jr $31指令就是回到调用过程。
// 进入临界区域

下一次将改动OpenMIPS以实现LL、SC指令

自己动手写CPU之第九阶段(7)——MIPS32中的LL、SC指令说明的更多相关文章

  1. 自己动手写CPU之第九阶段(8)——MIPS32中的LL、SC指令说明

    将陆续上传新书<自己动手写CPU>,今天是第47篇. 9.7 ll.sc指令实现思路 9.7.1 实现思路 这2条指令都涉及到訪问链接状态位LLbit,能够将LLbit当做寄存器处理,ll ...

  2. 自己动手写CPU之第九阶段(4)——载入存储指令实现思路

    将陆续上传新书<自己动手写CPU>,今天是第40篇,我尽量每周四篇,可是近期已经非常久没有实现这个目标了,一直都有事,不好意思哈. 开展晒书评送书活动,在q=%E4%BA%9A%E9%A9 ...

  3. 自己动手写CPU之第九阶段(2)——载入存储指令说明2(lwl、lwr)

    将陆续上传新书<自己动手写CPU>.今天是第38篇,我尽量每周四篇,可是近期已经非常久没有实现这个目标了.一直都有事,不好意思哈. 开展晒书评送书活动,在q=%E4%BA%9A%E9%A9 ...

  4. 自己写CPU第四阶段(2)——验证该第一指令ori实现效果

    我们会继续上传新书<自己写CPU>(未公布),今天是12片,四篇 书名又之前的<自己动手写处理器>改为<自己动手写CPU> 4.3 验证OpenMIPS实现效果 4 ...

  5. 自己动手写CPU之第七阶段(7)——乘累加指令的实现

    将陆续上传本人写的新书<自己动手写CPU>.今天是第30篇.我尽量每周四篇 亚马逊的销售地址例如以下.欢迎大家围观呵! http://www.amazon.cn/dp/b00mqkrlg8 ...

  6. 自己动手写CPU之第五阶段(1)——流水线数据相关问题

    将陆续上传本人写的新书<自己动手写CPU>(尚未出版),今天是第15篇,我尽量每周四篇 上一章建立了原始的OpenMIPS五级流水线结构,可是仅仅实现了一条ori指令,从本章開始,将逐步完 ...

  7. 自己动手写CPU之第六阶段(2)——移动操作指令实现思路

    将陆续上传本人写的新书<自己动手写CPU>(尚未出版),今天是第21篇,我尽量每周四篇 6.2 移动操作指令实现思路 6.2.1 实现思路 这6条移动操作指令能够分为两类:一类是不涉及特殊 ...

  8. 自己写CPU第九阶段(5)——实现负载存储指令2(改变运行阶段)

    我们会继续上传新书<自己动手写CPU>.今天是第42篇.我尽量每周四篇,可是近期已经非常久没有实现这个目标了,一直都有事.不好意思哈. 开展晒书评送书活动,在q=%E4%BA%9A%E9% ...

  9. 自己动手写CPU之第四阶段(3)——MIPS编译环境的建立

    将陆续上传本人写的新书<自己动手写CPU>(尚未出版).今天是第13篇.我尽量每周四篇 4.4 MIPS编译环境的建立 OpenMIPS处理器在设计的时候就计划与MIPS32指令集架构兼容 ...

随机推荐

  1. python-通过openpy操作excel

    1.安装 openpyxl pip install openpyxl == 2.3.5  安装指定版本 遇到问题: 查询结果:这是因为电脑上有其他软件也有pip命令,我的电脑上是因为装了loadrun ...

  2. HDU 3879 Base Station

    Base Station Time Limit: 2000ms Memory Limit: 32768KB This problem will be judged on HDU. Original I ...

  3. ffmpeg常见名词解析

    scan_all_pmts, 扫描全部的ts流的"Program Map Table"表.

  4. Dialog共通写法(一个button)

    一个button的: package jp.co.hyakujushibank.view import android.app.Dialogimport android.content.Context ...

  5. POJ——2251Dungeon Master(三维BFS)

    Dungeon Master Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 25379   Accepted: 9856 D ...

  6. leetcode 206 头插法

    头插法,定义temp,Node temp指向每次头结点,Node每次指向要进行头插的节点. 最后返回temp /** * Definition for singly-linked list. * st ...

  7. scrapy介绍及源码分析

    一 简介 Scrapy基于事件驱动网络框架 Twisted 编写.因此,Scrapy基于并发性考虑由非阻塞(即异步)的实现. 官方文档 :https://docs.scrapy.org/en/late ...

  8. 酒厂选址(codevs 1507)

    题目描述 Description Abstinence(戒酒)岛的居民们酷爱一种无酒精啤酒.以前这种啤酒都是从波兰进口,但今年居民们想建一个自己的啤酒厂.岛上所有的城市都坐落在海边,并且由一条沿海岸线 ...

  9. tyvj 1432 楼兰图腾

    树状数组 本题数据有误 对于每一个点用权值树状数组维护在这个点之后之前的比他大和比他小的数 #include <iostream> #include <cstdio> #inc ...

  10. 频繁项挖掘算法Apriori和FGrowth

    一:背景介绍 最近在公司用spark的平台做了一个购物车的推荐,用到的算法主要是FGrowth算法,它是Apriori算法的升级版,算法的主要目的是找出频繁进行一起购买的商品.本文主要介绍两个算法的背 ...