寄存器储值计算
先导知识
.asciiz
伪指令.asciiz以字节为单位存储字符串,其中每一个字符占一个字节。但需要注意的是此字符串的结尾有’\0’。
以.ascizz "Hello world"为例,字符串大小为12byte,中的可见字符有11个(有空格),占11个字节,末尾’\0‘占一个字节,总共有12byte。
.byte
伪指令.byte以字节为单位申请空间,.byte后可以跟若干个以逗号隔开的数字,每一个数字表示在申请的连续空间中,每一个字节的空间所存储的值。
.data 0x00000000
num .byte 1,2,3,4,5,6,7,8
以上述代码为例,.data 指明了数据的开始地址,即0x0000000,.byte创建了8个byte的空间,每一个字节存储相应的数字,从地址0x00000000开始到0x00000007,每一个字节分别存储1到8。
这里要注意的是,每一个数字是以一个字节的大小存储的,在二进制是八位大小,换算到16进制下,占16进制的两位,所以上例,每一个字节所存储的数据分别为0x01到0x08。
li
加载立即数,可以将立即数形式的地址存入到寄存器中。
lw sw
lw rt,offset(base)
加载字,从base的起始地址向后移动offest个字节后的位置开始向rt中加载一个字(4 byte)的数据。
sw rt,offset(base)
存储字,向base的起始地址向后移动offest个字节后的位置存入rt中的数组数据,占一个字。
lb sb(拓展)
例题
分别为加载字节和存储字节,在之后的字符串的单个字符处理处理中会经常用到。
以教程中的题为例,说明data中的数据是如何存储的以及寄存器中的值是如何获取的。
从先导知识可以明白我们的data部分从地址0x00001000开始,同时分配了总共(11+1)+8=20字节的空间(至于加一是为什么,应该上面已经明白了)。
我们可以画一个内存中数据的排布
data
0x00001000 | 0x00001001 | 0x00001002 | 0x00001003 | 0x00001004 | 0x00001005 | 0x00001006 | 0x00001007 | 0x00001008 | 0x00001009 |
---|---|---|---|---|---|---|---|---|---|
h | e | l | l | o | space | w | o | r | l |
0x0000100a | 0x0000100b | 0x0000100c | 0x0000100d | 0x0000100e | 0x0000100f | 0x00001010 | 0x00001011 | 0x00001012 | 0x00001013 |
d | \0 | 0x01 | 0x02 | 0x03 | 0x04 | 0x05 | 0x06 | 0x07 | 0x08 |
li a 0 , 0 x 00001000 将地址 0 x 00001000 存入了 a0 ,0x00001000 将地址0x00001000存入了 a0,0x00001000将地址0x00001000存入了a0寄存器
lw t 0 , 12 ( t0,12( t0,12(a0) 结合先导的解释,即从$a0存储的地址向后偏移12位,即从0x0000100c开始加载一个字的数据,即四个字节。
那么是不是就是依次取0x01,0x02,0x03,0x04, 然后$t0的值就是0x01020304呢?答案是不是的,我们要知道数据存储的规律。数据是从低位向高位存储,可能这里大家还不太清楚,我们以一个可视化的例子为例:
.data
str: .asciiz "Hello world"
我们将这段代码放进MARs编译后,我们可以看见value0中竟然是 l l e H
数据是从低位到高位存储的,那么就是说是先将H放入最低位(H),然后将e放入第二位(eH),然后将l放入第三位(leH),最后将l放入第四位(lleH)。
所以,我们以此类推,回到例题,我们要分别存入0x01到0x04,那么我们应该存储方式就是
0x04 0x03 0x02 0x01
最后加载到$t0中的一个字的数据为
0x04030201
一下为cys大佬讲解,我仅为搬运
补充说明字节存储顺序,具体细节可自行查找资料了解:
字节序`分为两种,和,其中`小端序(Little-endian)``大端序(Big-endian)
- 小端序:低位字节存入低地址,高位字节存入高地址
- 大端序:高位字节存入低地址,低位字节存入高地址
不同的CPU、不同的数据传输过程会可能选用不同的字节序,部分MIPS处理器是大端序,部分MIPS处理器是小端序,还有些MIPS处理器同时支持两种字节序,可根据实际需要进行切换。
本课程所用的MARS MIPS模拟器
使用的是小端字节序,即数据从低位字节开始到高位字节依次从低地址开始向高地址逐字节存入,取出时采用存储的逆操作。