首页 > 代码库 > 自己动手写CPU之第九阶段(3)——加载存储指令说明2(swl、swr)
自己动手写CPU之第九阶段(3)——加载存储指令说明2(swl、swr)
将陆续上传新书《自己动手写CPU》,今天是第39篇,我尽量每周四篇,但是最近已经很久没有实现这个目标了,一直都有事,不好意思哈。
开展晒书评送书活动,在亚马逊、京东、当当三大图书网站上,发表《自己动手写CPU》书评的前十名读者,均可获赠《步步惊芯——软核处理器内部设计分析》一书,大家踊跃参与吧!活动时间:2014-9-11至2014-10-30
今天继续对MIPS32中加载存储指令进行说明(主要是swl、swr),上次已经介绍一些其他的加载存储指令,大家可以回顾。
9.1.5 存储指令swl、swr说明
存储指令swl、swr的格式如图9-12所示。
- 当指令中的指令码为6‘b101010时,是swl指令,非对齐存储指令,向左存储
指令用法为:swl rt, offset(base)
指令作用为:将地址为rt的通用寄存器的高位部分存储到内存中指定的地址处,存储地址的最后两位确定了要存储rt通用寄存器的哪几个字节。swl指令对存储地址没有对齐要求,这是与前面介绍的sh、sw指令的不同之处。在大端模式、小端模式下,swl指令的效果不同,因为OpenMIPS是大端模式,所以此处只介绍在大端模式下swl指令的效果。假设计算出来的存储地址是storeaddr,storeaddr最低两位的值为n,storeaddr最低两位设为0后的值称为storeaddr_align,如下。
存储地址storeaddr = signed_extended(offset) + GPR[base]
n = storeaddr[1:0]
storeaddr_align = storeaddr – n
例如:假设计算出来的存储地址是5,swl指令要向地址5存储数据,那么storeaddr就等于5,n等于1,storeaddr_align等于4。
swl指令的作用是将地址为rt的通用寄存器的最高4-n个字节存储到地址storeaddr处。
继续上例,此时storeaddr_align为4,n为1,所以将地址rt的通用寄存器的最高3个字节存储到从地址5开始处,对应的是地址为5、6、7的三个字节,如图9-13所示。一个更加通用的描述如图9-14所示。
- 当指令中的指令码为6‘b101110时,是swr指令,非对齐存储指令,向右存储
指令用法为:swr rt, offset(base)
指令作用为:将地址为rt的通用寄存器的低位部分存储到内存中指定的地址处,存储地址的最后两位确定了要存储rt通用寄存器的哪几个字节。还是假设计算出来的存储地址是storeaddr,storeaddr的最低两位的值为n,storeaddr最低两位设为0后的值称为storeaddr_align,如下。
存储地址storeaddr = signed_extended(offset) + GPR[base]
n = storeaddr[1:0]
storeaddr_align = storeaddr – n
例如:假设计算出来的存储地址是9,swr指令要向地址9存储数据,那么storeaddr就等于9,n等于1,storeaddr_align等于8。
swr指令的作用是将地址为rt的通用寄存器的最低n+1个字节存储到地址storeaddr_align处。
继续上例,此时storeaddr_align为8,n为1,所以将地址rt的通用寄存器的最低2个字节存储到从地址8开始处,对应的是地址为8、9的两个位置,如图9-15所示。一个更加通用的描述如图9-16所示。
swl与swr指令配合可以实现向一个非对齐地址存储一个字,而且只需要使用2条指令,提高了效率。例如:使用一般指令向地址7处存储一个字,那么可以使用以下代码实现,共5条指令。
sll $2, $1, 24 # 要存储的数据在$1中,将$1的最高字节存储到$2 sb $2, 7($0) # 存储最高字节到地址为7的内存处 sll $2, $1, 8 # 将$1的第2、1字节保存到$2中 sh $2, 8($0) # 存储第2、1字节到地址为8、9的内存处 sb $1, 10($0) # 存储第0字节到地址为10的内存处
而有了swl、swr指令后,只需要2条指令即可。如下,图9-17是对这个过程的描述。
swl $1, 7($0) swr $1, 10($0)
自己动手写CPU之第九阶段(3)——加载存储指令说明2(swl、swr)