在MIPS中声明整数值

时间:2015-09-06 05:46:13

标签: mips

所以我正在编写一个包含许多常量整数值的汇编程序。

我知道在.data部分我可以分配一个带有.word数据类型的标签并输入我的号码。使用这种方法,我仍然需要在main中加载一个地址。

但在主要方面,我可以简单地使用

li $ t1,some_number

这些方法中的任何一种方法都比其他方法更好吗?为什么?

1 个答案:

答案 0 :(得分:0)

一般来说,我说使用li是更好的方法。您在.data部分中避免添加一堆混乱,并且在某些情况下您还可以获得更高效的代码。

让我们看看一些例子:

.data
ten: .word 10
million: .word 1000000

.text 
main:
    lw $t0,ten
    li $t1,10
    lw $t2,million
    li $t3,1000000

在此理解这一点非常重要,lwli都是伪指令,它们会被翻译成一个或多个实际指令。 lw 存在于MIPS指令集中,但它的这个特定变体并不存在。 MIPS指令集中不存在li

如果我们看一下SPIM为前两条指令生成的内容,我们会看到:

[0x00400024]    0x3c011001  lui $1, 4097                    ; 9: lw $t0,ten
[0x00400028]    0x8c280000  lw $8, 0($1)

[0x0040002c]    0x3409000a  ori $9, $0, 10                  ; 10: li $t1,10

这是lw变体的另一条附加指令,因为首先必须将地址加载到寄存器中,然后从该地址加载该值。这也意味着一个额外的(可能很慢的)内存访问(如果计算取指令数,则为两个)。

现在让我们看看另外两条指令,其中要加载的值太大而无法在单条指令中编码:

[0x00400030]    0x3c011001  lui $1, 4097                    ; 11: lw $t2,million
[0x00400034]    0x8c2a0004  lw $10, 4($1)

[0x00400038]    0x3c01000f  lui $1, 15                      ; 12: li $t3,1000000
[0x0040003c]    0x342b4240  ori $11, $1, 16960

这里使用两个指令(15 << 16) | 16960加载即时1000000。因此,这两种变体都需要两条指令,但li变体不需要从内存中读取。

如果您想为常量指定一个有意义的名称,以避免在代码中包含幻数,您可以使用=执行此操作:

TEN = 10

li $t0, TEN   # Expands to li $t0, 10

你可以通过lw - 相对寻址来避免一直加载$gp的地址,但我觉得这超出了这个范围问题