4

参照によると、la(ロードアドレス)の擬似コードは次のように変換されます。

Pseudo : la $1, Label   

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

しかし、MARSでコードをアセンブルしようとすると、次のエラーが発生します。

"無効な言語要素:16]

[31:16]の部分を削除すると、

「ラベル」:オペランドのタイプが正しくありません

何か案が?

4

2 に答える 2

6

これは、ラベルの最上位16ビットが$1に設定されていることを意味します。次に、16個の最下位ビットが16個の最上位ビットとor'edされます。

ここにlui命令の説明があります。レジスタにラベルアドレスの16msbビットをロードし、16lsbをゼロにします。

このようにして、32ビット命令で32ビットアドレス(mips32)をロードできます。

それは決して「実際のコード」を意図したものではありません。[31:16] / [15:0]の部分は有効なミップではなく、ビットの動きを理解するためだけにあります。

編集:あなたのコメントに応じて、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
于 2009-10-08T02:14:01.500 に答える
2

それは本当に良い質問です。そこで私は可能な解決策にたどり着きました。上記の答えは無条件に機能しません。

実際には、データセグメントをどこに配置するかを言うことができるはずです(たとえば、SPIMを使用するとそれが可能になります)。ディレクティブは、このデータセグメントを配置する必要がある32ビットアドレスという.data1つのオプションの引数を取ります。このようにして、例外ハンドラーが作成されます(.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が保存されています。このアプローチは、メモリ内にポインタを作成します。ポインターのオフセットを簡単に計算できるように、ポインターを他の可変長データの前に配置することをお勧めします。

于 2015-12-20T17:45:43.913 に答える