for (i = 0; i < 64; i++) {
A[i] = B[i] + C[i];
}
上述C代码的MIPS指令是:
add $t4, $zero, $zero # I1 i is initialized to 0, $t4 = 0
Loop:
add $t5, $t4, $t1 # I2 temp reg $t5 = address of b[i]
lw $t6, 0($t5) # I3 temp reg $t6 = b[i]
add $t5, $t4, $t2 # I4 temp reg $t5 = address of c[i]
lw $t7, 0($t5) # I5 temp reg $t7 = c[i]
add $t6, $t6, $t7 # I6 temp reg $t6 = b[i] + c[i]
add $t5, $t4, $t0 # I7 temp reg $t5 = address of a[i]
sw $t6, 0($t5) # I8 a[i] = b[i] + c[i]
addi $t4, $t4, 4 # I9 i = i + 1
slti $t5, $t4, 256 # I10 $t5 = 1 if $t4 < 256, i.e. i < 64
bne $t5, $zero, Loop # I11 go to Loop if $t4 < 256
对于I8,sw
指令是否可以不用addi
指令替换?即addi $t5, $t6, 0
它是否会实现将$t6
的地址复制到$t5
的相同任务?我想知道它们之间的区别以及何时使用它们。关于lw
指令也可以这么说。
另外,也许是一个相关的问题,MIPS如何处理指针?
编辑:更改了addi $ t6,$ t5,0。
答案 0 :(得分:4)
MIPS中的sw
指令将第一个参数($ t6中的值)存储到第二个参数中的地址($ t5中的值)偏移常量值(0)。
您实际上并没有尝试将$ t5地址存储到寄存器中,而是将$ t6中的值存储到$ t5值所代表的内存位置。
如果您愿意,可以将$t5
中的值视为与C指针类似。换句话说,MIPS不会以不同方式处理指针与值 - 所有重要的是您使用值的位置。如果使用寄存器的值作为lw
或sw
的第二个参数,那么您实际上是使用该寄存器作为指针。如果使用寄存器的值作为lw
或sw
的第一个参数,或者在大多数其他位置使用,则直接对该值进行操作。 (当然,就像在C指针算法中一样,你可以操作一个地址,这样你就可以在内存中的其他地方存储一段数据。)
答案 1 :(得分:3)
对于I8,sw指令是否可以用add指令替换?它不会实现将$ t5的地址复制到$ t0的相同任务吗?我想知道不同之处以及何时使用其中任何一种。
我认为你对商店词实际上的含义感到困惑。在I8中,$ t6中寄存器的值存储在零位置的$ t5中。添加将覆盖目标寄存器中存储的任何数据,其中包含两个其他寄存器值的总和。
另外,也许是一个相关的问题,MIPS如何处理指针?
“指针”只是存储在寄存器中的存储器中的地址(与值相反)。
答案 2 :(得分:3)
lw
和sw
读/写内存。 addi
和其他算术运算对寄存器进行操作。
寄存器就像CPU用来存储数据的小桶。如果我能正确记住我的MIPS架构,它们可以以5位左右的速度进行寻址。
存储器就像一个巨大的数据海洋,需要超过16位才能解决。所以你实际上必须将地址存储在寄存器中。
指针只是内存地址(32位架构上的32位)。
答案 3 :(得分:3)
对于I8,sw指令是否可以用addi指令替换?即addi $ t6,$ t5,0
没有。 sw
指令将结果存储到内存中。 add
只是操纵寄存器。 lw
从记忆中得到一个词。这是唯一一个这样做的MIPS指令。 (其他处理器可能并且确实具有访问内存的add
版本,但不能访问MIPS。)
使用汇编语言时,有必要调整思路。寄存器和内存是分开的。在更高级语言中,寄存器(几乎)完全隐藏。在汇编中,寄存器是程序员必须管理的独立资源。而且它们是稀缺资源。 HLL编译器会为您执行此操作,但通过汇编编程,您已经完成了自己的工作。
MIPS如何处理指针?
在MIPS中,指针只是整数(在寄存器或内存中),恰好是内存地址。他们与数据值区别开来的唯一方法就是你的大脑。 “指针”是高级语言设计者发明的一种东西,可以减轻程序员的负担。如果你仔细观察,你会发现$t5
实际上有一个指针。它是lw
和sw
用作加载或存储的地址的内存地址。