指令说明
加载指令
31-26 | 25-21 | 20-16 | 15-0 | useage | function |
---|---|---|---|---|---|
LB(100000) | base | rt | offset | lb rt,offset(base) | 从内存中指定加载处,读取一个字节,然后符号扩展到32位,保存到地址为rt的寄存器中 |
LBU(100100) | base | rt | offset | lbu rt,offset(base) | 同上,除有符号变无符号外 |
LH(100001) | base | rt | offset | lh rt,offset(base) | 从内存中指定加载处,读取一个半字,然后无符号扩展到32位,保存到地址为rt的寄存器中,该指令有地址对齐要求,要求加载地址的最低位为0 |
LHU(100101) | base | rt | offset | lhu rt,offset(base) | 同上,除有符号变为无符号外 |
LW(100011) | base | rt | offset | lw rt,offset(base) | 从内存中指定的加载地址处,读取一个字,保存到地址为rt的通用寄存器中。该指令有地址对齐要求,要求加载地址的最低位为00 |
LWL(100010) | base | rt | offset | lwl rt,offset(base) | 从内存中指定的加载地址处,加载一个字的最高有效部分lwl指令对加载地址没有要求,允许地址非对齐加载 |
LWR(100110) | base | rt | offset | lwr rt,offset(base) | 从内存中指定的加载地址处,加载一个字的最低有效部分,非对齐加载指令,向右加载 |
- lwl
加载地址=offset符号扩展到32位的值+地址为base的通用寄存器的值
假设计算出来的加载地址是loadaddr,loadaddr的最低两位是n,将loadaddr最低两位设为0后的值为loadaddr_align。
loadaddr=signed_extended(offset)+GPR(base)
n=loadaddr[1:0]
loadaddr_align=loadaddr-n - lwr
假设计算出来的加载地址是loadaddr,loadaddr的最低两位的值为n,将loadaddr最低两位设为0后的值称为loadaddr_align。
loadaddr=signed_extended(offset)+GPR(base)
n=loadaddr[1:0]
loadaddr_align=loadaddr-n
存储指令
31-26 | 25-21 | 20-16 | 15-0 | useage | function |
---|---|---|---|---|---|
SB(101000) | base | rt | offset | sb rt,offset(base) | 将地址为rt的通用寄存器的最低字节存储到内存中的指定地址 |
SH(101001) | base | rt | offset | sh rt offset(base) | 将地址为rt的通用寄存器的最低两个字节存储到内存中的指定地址。该指令有地址对齐要求,要求计算出来的存储地址最低位为0 |
SW(101011) | base | rt | offset | sw rt,offset(base) | 将地址为rt的通用寄存器的值存储到内存中的指定地址。该指令有地址对齐要求,要求计算出来的存储地址的最低位为00 |
SWL(101010) | base | rt | offset | swl rt,offset(base) | 将地址为rt的通用寄存器的高位部分存储到内存中指定的地址处,存储地址的最后两位确定了要存储rt通用寄存器的哪几个字节。swl指令对存储地址没有对齐要求 |
SWR(101110) | base | rt | offset | swr rt,offset(base) | 将地址为rt的通用寄存器的低位部分存储到内存中的指定地址处,存储地址的最后两位确定了要存储rt通用寄存器的哪几个字节。swr指令对存储地址没有对齐要求 |
存储地址=offset符号扩展到32位的值+地址为base的通用寄存器的值
- swl
storeaddr=signed_extended(offset)+GPR(base)
n=storeaddr[1:0]
storeaddr_align=storeaddr-n - swr
storeaddr=signed_extended(offset)+GPR(base)
n=storeaddr[1:0]
storeaddr_align=storeaddr-n
=============================================================
好烦啊 用法真烦。。。真是坠了
加载指令用法示例
OpenMIPS处理器是按字节寻址,且是大端模式。数据的高位保存在存储器的低地址中,而数据的低位保存在存储器的高地址中。
sh
使用sh指令在0x54处存储0x8281
sh指令(将地址为rt的通用寄存器的最低两个字节存储到内存中的指定地址。该指令有地址对齐要求,要求计算出来的存储地址最低位为0)
0x8281高位0x82在低地址0x54处存储,低位0x81在低地址0x55处存储。
sb
使用sb指令在0x50处存储0x81。
sb指令(将地址为rt的通用寄存器的最低字节存储到内存中的指定地址
sw
使用sw指令在0x58处存储0x84838281。
sw指令(将地址为rt的通用寄存器的值存储到内存中的指定地址。该指令有地址对齐要求,要求计算出来的存储地址的最低位为00)
lbu
此时使用加载指令lbu从0x58处加载一个字节。
lbu(从内存中指定加载处,读取一个字节,然后无符号扩展到32位,保存到地址为rt的寄存器中)。
读出的字节是0x84,经无符号扩展至32位是0x00000084。
lb
使用指令lb从0x58处加载一个字节。
读出来的字节是0x84,经有符号扩展是0xffffff84。
lhu
使用指令lhu从0x58处加载一个半字。读出来的半字就是0x8483,经无符号扩展至32位就是0x00008483。
lh
使用指令lh从0x58处加载一个半字。读出来的半字就是0x8483,经有符号扩展至32位就是0xffff8483。
字节与半字(32位处理器)
所以一个半字是两个字节。
lh(从内存中指定加载处,读取一个半字,然后无符号扩展到32位,保存到地址为rt的寄存器中,该指令有地址对齐要求,要求加载地址的最低位为0)
使用lh从0x59处加载一个半字,如果不考虑对齐要求,就是0x8382,(32’b00001111_00000011_00001111_00000010)。考虑到加载地址的最低位是0x59(32’b0000_0000_0000_0101_0000_0000_0000_1001)最低位不是0舍去。
使用lh从0x5a处加载一个半字,就是0x8281,无符号扩展至32位就是0x00008281
lw
使用lw从0x58处加载一个字,读出来的字就是4个字节。0x84838281
lwl
假设计算出来的加载地址是5,lwl指令要从地址5加载数据,那么loadaddr=5(0101),n=2’b01=1,loadaddr_align=5-1=4。从4处加载一个字,即4,5,6,7的字节,因为n=1所以将加载到的字的最低3个字节保存到地址为rt的通用寄存器的最高三个字节。从地址为loadaddr_align处加载一个字,4个字节,然后将这个字的最低4-n个字节保存到地址为rt的通用寄存器的高位,低位保持不变。
lwr
假设计算出来的加载地址是9,lwr指令要从地址9加载数据,那么loadaddr=9,n=1,loadaddr_align=8。从地址为loadaddr_align处加载一个字,4个字节,然后将这个字的最高n+1个字节保存到地址为rt的通用寄存器的低位,并保持高位不变。(和lwl相反)从地址为8处加载一个字,对应的地址是8,9,10,11的字节,n=1,将加载到的字的最高两个字节保存到地址为rt的通用寄存器的低2字节。
swl
swr
浅记一下。