【问题标题】:MIPS: The Equivalent of la instruction without using pseudo codes?MIPS:不使用伪代码的 la 指令的等价物?
【发布时间】:2009-10-08 02:00:17
【问题描述】:

参考资料说 la(加载地址)的伪代码被翻译为:

Pseudo : la $1, Label   

lui $1, Label[31:16]
ori $1,$1, label[15:0]

但是当我尝试在 MARS 中组装代码时,我得到了错误:

"无效的语言元素:16]

如果我删除 [31:16] 部分,我会得到 ​​p>

“标签”:操作数类型不正确

有什么想法吗?

【问题讨论】:

标签: assembly mips


【解决方案1】:

这意味着标签的 16 个最高有效位设置在 $1 中。然后,将 16 个较低有效位与 16 个最高有效位进行或运算。

Here你可以找到lui指令的描述。它在寄存器上加载标签地址的 16 msb 位并将 16 lsb 归零。

这样,您可以使用 32 位指令加载 32 位地址(在 mips32 中)。

它绝不是“真正的代码”。 [31:16] / [15:0] 部分不是有效的 mips,仅供您了解位移动。

编辑: 为了回应您的评论,您必须知道要使用 lui 指令加载的地址。为此,您可以使用标签来指示所需的地址。 例如

.data 
my_var: .asciiz "This is a nul terminated string"

.text
        andi $a0,$a0,0x0000ffff
        lui $a0,my_var
        ori $a0,$a0,my_var

【讨论】:

  • 谢谢,但是如果我想在没有伪代码的情况下做同样的事情,我应该写什么?
  • 由于 my_var 是 32 位地址而 lui oprand 应该是 16 位,因此此代码无法组合。
  • 这不适用于 qtspim 它给我语法错误
  • 该示例代码不起作用,因为 lui 将低 16 位覆盖为全 0,并且您在 $a0 中有什么与您进行 ANDint 的?此外,您的常数是 32 位长,但 andi 指令是 I 格式,它可以采用的最大常数是 16 位长。
【解决方案2】:

这是一个非常好的问题,我自己找到了一个可能的解决方案。上面的答案不是无条件的。

实际上,应该可以说您希望数据段位于何处(例如,SPIM 允许您这样做)。 .data 指令采用一个可选参数,即该数据段应位于的 32 位地址。以这种方式编写异常处理程序(仅使用.kdata 而不是.data)。

一个例子:

.data 0x10001000                 #remember this location
    .align 0
    .asciiz "MIPS IS GREAT!"     #this is at offset 0

.text
    .align 2
    .globl main
main:                            #let's assume we've got no arguments
    addiu $sp, $sp, -24          #subroutine prolog
    sw $ra, 16($sp)
    sw $fp, 10($sp)
    addiu $fp, $sp, 20

    ori $v0, $0, 4
    lui $a0, 0x1000              #sole argument must be str pointer
    ori $a0, $a0, 0x1000
    syscall                      #print STR out on console

    lw $ra, 16($sp)              #subroutine epilog
    lw $fp, 10($sp)
    addiu $sp, $sp, 24
    jal

我实际上不确定这是否是最好的解决方案,但它是我能想到的唯一解决方案(即使不使用虚拟寻址模式,即加载或存储指令的标签)并且这个想法应该可行(无论我的代码示例有效,我不知道,我没有测试过)。

编辑: 我刚刚玩过,发现了一个非常棒的技巧,它允许我们在没有任何伪指令和自然寻址模式的情况下将标签加载到寄存器中。我的例子:

.data 0x10001000
        .word LABEL
LABEL:  .asciiz "Get LABEL to print this C string."

.text
    .align 2
    .globl main
#test if it loads LABEL
main:
    lui $4, 0x1000
    ori $4, $4, 0x1000
    lw $4, 0($4)
    ori $2, $0, 4
    syscall

在 SPIM 中它组装得很好!查看 0x10001000 处的内存显示,0x10001004 被存储!这种方法在内存中创建一个指针。我建议将指针放在其他可变长度数据的前面,以便您可以轻松计算指针的偏移量。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-03
    相关资源
    最近更新 更多