在MIPS中声明整数值 [英] Declaring integer values in MIPS

查看:472
本文介绍了在MIPS中声明整数值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我正在编写一个具有很多恒定整数值的汇编程序.

So I am writing an assembly program that has lots of constant integer values.

我知道在.data部分中,我可以为标签分配一个.word数据类型,然后键入我的电话号码.通过这种方法,我仍然必须在main中加载地址.

I know that in the .data section I can assign a label with a .word data type and type in my number. With this method I still have to load an address in main.

但是总的来说,我可以简单地使用

But in main, I could just simply use

li $ t1,some_number

这些方法中的任何一种是否比另一种更好?为什么?

Are any one of these methods better than the other and why?

推荐答案

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

Generally I'd say using li is the better approach. You're avoiding adding a bunch of clutter in your .data section, and you will also get more efficient code in some cases.

让我们看一些示例:

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

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

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

It's important to understand here that both lw and li are pseudo-instructions that get translated into one or more actual instructions. lw does exist in the MIPS instruction set, but this particular variant of it doesn't. li doesn't exist in the MIPS instruction set.

如果我们查看SPIM为前两个指令生成的内容,我们将看到:

If we look at what SPIM generates for the first two instructions, we see:

[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变体的另一条指令,因为首先必须将地址加载到寄存器中,然后再从该地址加载值.这也意味着一个额外的(可能很慢)的内存访问(嗯,如果算上指令提取,则是两个).

So that's one additional instruction for the lw variant, as the address first has to be loaded into a register, and then the value is loaded from that address. This also means one additional (potentially slow) memory access (well, two if you count the instruction fetch).

现在让我们看一下其他两个指令,其中要加载的值太大而无法在单个指令中进行编码:

Now let's look at the other two instructions, where the value to be loaded is too large to be encoded in a single instruction:

[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变体不需要从内存中读取.

Here the immediate 1000000 is loaded using two instructions as (15 << 16) | 16960. So both variants require two instructions, but the li variant doesn't need to read from memory.

如果要为常量分配一个有意义的名称,以避免在代码中各处都出现幻数,则可以使用=:

If you want to assign a meaningful name to a constant to avoid having magic numbers all over your code you can do so with =:

TEN = 10

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


您也许可以通过使用$gp相对寻址来避免一直加载lw的地址,但是我认为这超出了这个问题的范围.


You could perhaps avoid loading the addresses for lw all the time by using $gp-relative addressing, but I feel that that's beyond the scope of this question.

这篇关于在MIPS中声明整数值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆