将陆续上传新书《自己动手写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. java 协程框架kilim

    http://phl.iteye.com/blog/2247112 http://chen-tao.github.io/2015/10/02/kilim-work-way/ 待丰富

  2. Knockout v3.4.0 中文版教程-16-控制流-foreach绑定

    2. 控制流 1. foreach绑定 目的 foreach绑定会遍历一个数组,为每个数组项生成重复的元素标记结构并做关联.这在渲染列表或表格的时候特别有用. 假设你的数组是一个监控数组,之后无论你进 ...

  3. Leetcode 388.文件的最长绝对路径

    文件的最长绝对路径 假设我们以下述方式将我们的文件系统抽象成一个字符串: 字符串 "dir\n\tsubdir1\n\tsubdir2\n\t\tfile.ext" 表示: dir ...

  4. 【bzoj4889】[Tjoi2017]不勤劳的图书管理员 树状数组+分块+二分

    题目描述(转自洛谷) 加里敦大学有个帝国图书馆,小豆是图书馆阅览室的一个书籍管理员.他的任务是把书排成有序的,所以无序的书让他产生厌烦,两本乱序的书会让小豆产生这两本书页数的和的厌烦度.现在有n本被打 ...

  5. yum update 出错解决办法

    卸载掉yum和python 于是我卸载了python和yum,觉得自己重新安装python和yum. 步骤1:卸载python rpm -qa|grep python|xargs rpm -e --a ...

  6. 【leetcode最短路】818. Race Car

    https://leetcode.com/problems/race-car/description/ 1. BFS剪枝 0<=current position<=2*target.为什么 ...

  7. 【bzoj2751】[HAOI2012]容易题(easy) 数论,简单题

    Description 为了使得大家高兴,小Q特意出个自认为的简单题(easy)来满足大家,这道简单题是描述如下:有一个数列A已知对于所有的A[i]都是1~n的自然数,并且知道对于一些A[i]不能取哪 ...

  8. Explosion at Cafebazaar

    Explosion at Cafebazaar 时间限制: 1 Sec  内存限制: 128 MB 题目描述 You are an engineer at Cafebazaar and your sp ...

  9. miller_rabin + pollard_rho模版

    #include<stdio.h> #include<stdlib.h> #include<time.h> #include<math.h> #incl ...

  10. zoj 2081 BFS 延迟标记 读入问题

    Mission Impossible Time Limit: 2 Seconds                                     Memory Limit: 65536 KB  ...